summaryrefslogtreecommitdiffstats
path: root/image
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /image
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'image')
-rw-r--r--image/AnimationFrameBuffer.cpp471
-rw-r--r--image/AnimationFrameBuffer.h480
-rw-r--r--image/AnimationParams.h55
-rw-r--r--image/AnimationSurfaceProvider.cpp534
-rw-r--r--image/AnimationSurfaceProvider.h138
-rw-r--r--image/AutoRestoreSVGState.h72
-rw-r--r--image/BMPHeaders.h53
-rw-r--r--image/BlobSurfaceProvider.cpp310
-rw-r--r--image/BlobSurfaceProvider.h140
-rw-r--r--image/ClippedImage.cpp512
-rw-r--r--image/ClippedImage.h98
-rw-r--r--image/CopyOnWrite.h247
-rw-r--r--image/DecodePool.cpp203
-rw-r--r--image/DecodePool.h108
-rw-r--r--image/DecodedSurfaceProvider.cpp234
-rw-r--r--image/DecodedSurfaceProvider.h93
-rw-r--r--image/Decoder.cpp570
-rw-r--r--image/Decoder.h641
-rw-r--r--image/DecoderFactory.cpp446
-rw-r--r--image/DecoderFactory.h210
-rw-r--r--image/DecoderFlags.h56
-rw-r--r--image/Downscaler.cpp302
-rw-r--r--image/Downscaler.h146
-rw-r--r--image/DownscalingFilter.h312
-rw-r--r--image/DynamicImage.cpp298
-rw-r--r--image/DynamicImage.h69
-rw-r--r--image/FrameAnimator.cpp519
-rw-r--r--image/FrameAnimator.h343
-rw-r--r--image/FrameTimeout.h114
-rw-r--r--image/FrozenImage.cpp148
-rw-r--r--image/FrozenImage.h83
-rw-r--r--image/ICOFileHeaders.h77
-rw-r--r--image/IDecodingTask.cpp221
-rw-r--r--image/IDecodingTask.h121
-rw-r--r--image/IProgressObserver.h57
-rw-r--r--image/ISurfaceProvider.h346
-rw-r--r--image/Image.cpp261
-rw-r--r--image/Image.h419
-rw-r--r--image/ImageBlocker.cpp59
-rw-r--r--image/ImageBlocker.h33
-rw-r--r--image/ImageCacheKey.cpp170
-rw-r--r--image/ImageCacheKey.h87
-rw-r--r--image/ImageFactory.cpp277
-rw-r--r--image/ImageFactory.h88
-rw-r--r--image/ImageLogging.h185
-rw-r--r--image/ImageMemoryReporter.cpp185
-rw-r--r--image/ImageMemoryReporter.h95
-rw-r--r--image/ImageMetadata.h115
-rw-r--r--image/ImageOps.cpp248
-rw-r--r--image/ImageOps.h167
-rw-r--r--image/ImageRegion.h273
-rw-r--r--image/ImageWrapper.cpp289
-rw-r--r--image/ImageWrapper.h78
-rw-r--r--image/ImgDrawResult.h123
-rw-r--r--image/LookupResult.h137
-rw-r--r--image/MultipartImage.cpp300
-rw-r--r--image/MultipartImage.h81
-rw-r--r--image/Orientation.h111
-rw-r--r--image/OrientedImage.cpp349
-rw-r--r--image/OrientedImage.h102
-rw-r--r--image/PlaybackType.h40
-rw-r--r--image/ProgressTracker.cpp561
-rw-r--r--image/ProgressTracker.h264
-rw-r--r--image/RasterImage.cpp1785
-rw-r--r--image/RasterImage.h484
-rw-r--r--image/Resolution.h90
-rw-r--r--image/SVGDocumentWrapper.cpp401
-rw-r--r--image/SVGDocumentWrapper.h157
-rw-r--r--image/SVGDrawingCallback.h39
-rw-r--r--image/SVGDrawingParameters.h60
-rw-r--r--image/ScriptedNotificationObserver.cpp73
-rw-r--r--image/ScriptedNotificationObserver.h36
-rw-r--r--image/ShutdownTracker.cpp68
-rw-r--r--image/ShutdownTracker.h45
-rw-r--r--image/SourceBuffer.cpp706
-rw-r--r--image/SourceBuffer.h499
-rw-r--r--image/StreamingLexer.h751
-rw-r--r--image/SurfaceCache.cpp1970
-rw-r--r--image/SurfaceCache.h509
-rw-r--r--image/SurfaceCacheUtils.cpp17
-rw-r--r--image/SurfaceCacheUtils.h33
-rw-r--r--image/SurfaceFilters.h1454
-rw-r--r--image/SurfaceFlags.h78
-rw-r--r--image/SurfacePipe.cpp162
-rw-r--r--image/SurfacePipe.h848
-rw-r--r--image/SurfacePipeFactory.h679
-rw-r--r--image/VectorImage.cpp1642
-rw-r--r--image/VectorImage.h157
-rw-r--r--image/WebRenderImageProvider.h65
-rw-r--r--image/build/components.conf85
-rw-r--r--image/build/moz.build26
-rw-r--r--image/build/nsImageModule.cpp88
-rw-r--r--image/build/nsImageModule.h20
-rw-r--r--image/decoders/EXIF.cpp519
-rw-r--r--image/decoders/EXIF.h95
-rw-r--r--image/decoders/GIF2.h67
-rw-r--r--image/decoders/iccjpeg.c184
-rw-r--r--image/decoders/iccjpeg.h65
-rw-r--r--image/decoders/icon/android/moz.build13
-rw-r--r--image/decoders/icon/android/nsIconChannel.cpp125
-rw-r--r--image/decoders/icon/android/nsIconChannel.h45
-rw-r--r--image/decoders/icon/components.conf29
-rw-r--r--image/decoders/icon/gtk/moz.build20
-rw-r--r--image/decoders/icon/gtk/nsIconChannel.cpp483
-rw-r--r--image/decoders/icon/gtk/nsIconChannel.h53
-rw-r--r--image/decoders/icon/mac/moz.build13
-rw-r--r--image/decoders/icon/mac/nsIconChannel.h61
-rw-r--r--image/decoders/icon/mac/nsIconChannelCocoa.mm505
-rw-r--r--image/decoders/icon/moz.build39
-rw-r--r--image/decoders/icon/nsIconProtocolHandler.cpp68
-rw-r--r--image/decoders/icon/nsIconProtocolHandler.h25
-rw-r--r--image/decoders/icon/nsIconURI.cpp654
-rw-r--r--image/decoders/icon/nsIconURI.h118
-rw-r--r--image/decoders/icon/win/moz.build21
-rw-r--r--image/decoders/icon/win/nsIconChannel.cpp1006
-rw-r--r--image/decoders/icon/win/nsIconChannel.h65
-rw-r--r--image/decoders/moz.build62
-rw-r--r--image/decoders/nsAVIFDecoder.cpp1991
-rw-r--r--image/decoders/nsAVIFDecoder.h289
-rw-r--r--image/decoders/nsBMPDecoder.cpp1275
-rw-r--r--image/decoders/nsBMPDecoder.h285
-rw-r--r--image/decoders/nsGIFDecoder2.cpp1073
-rw-r--r--image/decoders/nsGIFDecoder2.h166
-rw-r--r--image/decoders/nsICODecoder.cpp709
-rw-r--r--image/decoders/nsICODecoder.h106
-rw-r--r--image/decoders/nsIconDecoder.cpp125
-rw-r--r--image/decoders/nsIconDecoder.h64
-rw-r--r--image/decoders/nsJPEGDecoder.cpp999
-rw-r--r--image/decoders/nsJPEGDecoder.h113
-rw-r--r--image/decoders/nsJXLDecoder.cpp163
-rw-r--r--image/decoders/nsJXLDecoder.h55
-rw-r--r--image/decoders/nsPNGDecoder.cpp1035
-rw-r--r--image/decoders/nsPNGDecoder.h148
-rw-r--r--image/decoders/nsWebPDecoder.cpp605
-rw-r--r--image/decoders/nsWebPDecoder.h105
-rw-r--r--image/encoders/bmp/moz.build15
-rw-r--r--image/encoders/bmp/nsBMPEncoder.cpp716
-rw-r--r--image/encoders/bmp/nsBMPEncoder.h150
-rw-r--r--image/encoders/ico/moz.build20
-rw-r--r--image/encoders/ico/nsICOEncoder.cpp499
-rw-r--r--image/encoders/ico/nsICOEncoder.h95
-rw-r--r--image/encoders/jpeg/moz.build11
-rw-r--r--image/encoders/jpeg/nsJPEGEncoder.cpp519
-rw-r--r--image/encoders/jpeg/nsJPEGEncoder.h74
-rw-r--r--image/encoders/moz.build13
-rw-r--r--image/encoders/png/moz.build17
-rw-r--r--image/encoders/png/nsPNGEncoder.cpp820
-rw-r--r--image/encoders/png/nsPNGEncoder.h79
-rw-r--r--image/encoders/webp/moz.build15
-rw-r--r--image/encoders/webp/nsWebPEncoder.cpp342
-rw-r--r--image/encoders/webp/nsWebPEncoder.h63
-rw-r--r--image/imgFrame.cpp729
-rw-r--r--image/imgFrame.h422
-rw-r--r--image/imgICache.idl106
-rw-r--r--image/imgIContainer.idl692
-rw-r--r--image/imgIContainerDebug.idl25
-rw-r--r--image/imgIEncoder.idl146
-rw-r--r--image/imgILoader.idl97
-rw-r--r--image/imgINotificationObserver.idl59
-rw-r--r--image/imgIRequest.idl276
-rw-r--r--image/imgIScriptedNotificationObserver.idl22
-rw-r--r--image/imgITools.idl207
-rw-r--r--image/imgLoader.cpp3334
-rw-r--r--image/imgLoader.h534
-rw-r--r--image/imgRequest.cpp1231
-rw-r--r--image/imgRequest.h296
-rw-r--r--image/imgRequestProxy.cpp1327
-rw-r--r--image/imgRequestProxy.h263
-rw-r--r--image/imgTools.cpp649
-rw-r--r--image/imgTools.h36
-rw-r--r--image/moz.build139
-rw-r--r--image/nsIIconURI.idl92
-rw-r--r--image/test/browser/animated.gifbin0 -> 71479 bytes
-rw-r--r--image/test/browser/animated2.gifbin0 -> 66647 bytes
-rw-r--r--image/test/browser/big.pngbin0 -> 129497 bytes
-rw-r--r--image/test/browser/browser.ini20
-rw-r--r--image/test/browser/browser_bug666317.js138
-rw-r--r--image/test/browser/browser_docshell_type_editor.js134
-rw-r--r--image/test/browser/browser_docshell_type_editor/chrome.manifest1
-rw-r--r--image/test/browser/browser_docshell_type_editor/img/privileged.pngbin0 -> 90 bytes
-rw-r--r--image/test/browser/browser_image.js261
-rw-r--r--image/test/browser/browser_mozicon_file.js12
-rw-r--r--image/test/browser/browser_mozicon_file_sandbox_headless.js13
-rw-r--r--image/test/browser/browser_offscreen_image_in_out_of_process_iframe.js164
-rw-r--r--image/test/browser/browser_sandbox_headless.ini8
-rw-r--r--image/test/browser/empty.html2
-rw-r--r--image/test/browser/head.js136
-rw-r--r--image/test/browser/image.html23
-rw-r--r--image/test/browser/imageX2.html14
-rw-r--r--image/test/crashtests/1205923-1.html36
-rw-r--r--image/test/crashtests/1210745-1.gifbin0 -> 23 bytes
-rw-r--r--image/test/crashtests/1212954-1.svg16
-rw-r--r--image/test/crashtests/1235605.gifbin0 -> 2360 bytes
-rw-r--r--image/test/crashtests/1241728-1.html17
-rw-r--r--image/test/crashtests/1241729-1.bmpbin0 -> 548 bytes
-rw-r--r--image/test/crashtests/1241729-1.html5
-rw-r--r--image/test/crashtests/1242093-1.html22
-rw-r--r--image/test/crashtests/1242778-1.pngbin0 -> 15929 bytes
-rw-r--r--image/test/crashtests/1249576-1.pngbin0 -> 1169 bytes
-rw-r--r--image/test/crashtests/1251091-1.html51
-rw-r--r--image/test/crashtests/1251091-1.pngbin0 -> 95370 bytes
-rw-r--r--image/test/crashtests/1253362-1.html11
-rw-r--r--image/test/crashtests/1262549-1.gifbin0 -> 428 bytes
-rw-r--r--image/test/crashtests/1277397-1.jpgbin0 -> 266 bytes
-rw-r--r--image/test/crashtests/1277397-2.jpgbin0 -> 1407 bytes
-rw-r--r--image/test/crashtests/1355898-1.html45
-rw-r--r--image/test/crashtests/1375842-1.html16
-rw-r--r--image/test/crashtests/1413762-1.gifbin0 -> 7866 bytes
-rw-r--r--image/test/crashtests/1443232-1.gifbin0 -> 42434 bytes
-rw-r--r--image/test/crashtests/1443232-1.html30
-rw-r--r--image/test/crashtests/1509998.gifbin0 -> 92 bytes
-rw-r--r--image/test/crashtests/1526717-1.html1
-rw-r--r--image/test/crashtests/1526717-1.pngbin0 -> 318 bytes
-rw-r--r--image/test/crashtests/1629490-1-iframe.html1
-rw-r--r--image/test/crashtests/1629490-1.html49
-rw-r--r--image/test/crashtests/1634839-1-iframe.html1
-rw-r--r--image/test/crashtests/1634839-1.html51
-rw-r--r--image/test/crashtests/1634839-2-iframe.html1
-rw-r--r--image/test/crashtests/1634839-2.html51
-rw-r--r--image/test/crashtests/1676172-1-iframe.html13
-rw-r--r--image/test/crashtests/1676172-1.gifbin0 -> 2439 bytes
-rw-r--r--image/test/crashtests/1676172-1.html57
-rw-r--r--image/test/crashtests/1763581-1-iframe.html15
-rw-r--r--image/test/crashtests/1763581-1.gifbin0 -> 70793 bytes
-rw-r--r--image/test/crashtests/1763581-1.html28
-rw-r--r--image/test/crashtests/1763581-1.sjs71
-rw-r--r--image/test/crashtests/1765871-1.jpgbin0 -> 6872 bytes
-rw-r--r--image/test/crashtests/1814553.avifbin0 -> 803330 bytes
-rw-r--r--image/test/crashtests/1814561.avifbin0 -> 2104 bytes
-rw-r--r--image/test/crashtests/1814677.avifbin0 -> 1607 bytes
-rw-r--r--image/test/crashtests/1814708.avifbin0 -> 1607 bytes
-rw-r--r--image/test/crashtests/1814741.avifbin0 -> 1607 bytes
-rw-r--r--image/test/crashtests/1814774.avifbin0 -> 2104 bytes
-rw-r--r--image/test/crashtests/1817108.avifbin0 -> 2105 bytes
-rw-r--r--image/test/crashtests/256-height.icobin0 -> 154 bytes
-rw-r--r--image/test/crashtests/256-width.icobin0 -> 154 bytes
-rw-r--r--image/test/crashtests/463696.bmpbin0 -> 1272 bytes
-rw-r--r--image/test/crashtests/523528-1.gifbin0 -> 132 bytes
-rw-r--r--image/test/crashtests/523528-2.gifbin0 -> 132 bytes
-rw-r--r--image/test/crashtests/570451.pngbin0 -> 114 bytes
-rw-r--r--image/test/crashtests/694165-1.xhtml510
-rw-r--r--image/test/crashtests/732319-1.html2
-rw-r--r--image/test/crashtests/83804-1.gifbin0 -> 37 bytes
-rw-r--r--image/test/crashtests/844403-1.html10
-rw-r--r--image/test/crashtests/856616.gifbin0 -> 27 bytes
-rw-r--r--image/test/crashtests/89341-1.gifbin0 -> 769 bytes
-rw-r--r--image/test/crashtests/944353.jpgbin0 -> 610965 bytes
-rw-r--r--image/test/crashtests/colormap-range.gifbin0 -> 5657 bytes
-rw-r--r--image/test/crashtests/crashtests.list84
-rw-r--r--image/test/crashtests/delayedframe.sjs44
-rw-r--r--image/test/crashtests/delaytest.html59
-rw-r--r--image/test/crashtests/discardframe.htm1
-rw-r--r--image/test/crashtests/finite-apng.pngbin0 -> 5834 bytes
-rw-r--r--image/test/crashtests/ie.pngbin0 -> 466589 bytes
-rw-r--r--image/test/crashtests/invalid-disposal-method-1.gifbin0 -> 167 bytes
-rw-r--r--image/test/crashtests/invalid-disposal-method-2.gifbin0 -> 167 bytes
-rw-r--r--image/test/crashtests/invalid-disposal-method-3.gifbin0 -> 167 bytes
-rw-r--r--image/test/crashtests/invalid-icc-profile.jpgbin0 -> 2568 bytes
-rw-r--r--image/test/crashtests/invalid-size-second-frame.gifbin0 -> 673 bytes
-rw-r--r--image/test/crashtests/invalid-size.gifbin0 -> 329 bytes
-rw-r--r--image/test/crashtests/invalid_ico_height.icobin0 -> 894 bytes
-rw-r--r--image/test/crashtests/invalid_ico_width.icobin0 -> 894 bytes
-rw-r--r--image/test/crashtests/multiple-png-hassize.icobin0 -> 18096 bytes
-rw-r--r--image/test/crashtests/out2.gifbin0 -> 24129 bytes
-rw-r--r--image/test/crashtests/ownerdiscard.html48
-rw-r--r--image/test/crashtests/rainbow.gifbin0 -> 6171 bytes
-rw-r--r--image/test/crashtests/threeframes-end.gifbin0 -> 16 bytes
-rw-r--r--image/test/crashtests/threeframes-start.gifbin0 -> 92 bytes
-rw-r--r--image/test/crashtests/truncated-second-frame.pngbin0 -> 72247 bytes
-rw-r--r--image/test/crashtests/unsized-svg.svg1
-rw-r--r--image/test/fuzzing/TestDecoders.cpp180
-rw-r--r--image/test/fuzzing/moz.build24
-rw-r--r--image/test/gtest/Common.cpp1076
-rw-r--r--image/test/gtest/Common.h600
-rw-r--r--image/test/gtest/TestADAM7InterpolatingFilter.cpp595
-rw-r--r--image/test/gtest/TestAnimationFrameBuffer.cpp895
-rw-r--r--image/test/gtest/TestBlendAnimationFilter.cpp450
-rw-r--r--image/test/gtest/TestCopyOnWrite.cpp237
-rw-r--r--image/test/gtest/TestDecodeToSurface.cpp173
-rw-r--r--image/test/gtest/TestDecoders.cpp1142
-rw-r--r--image/test/gtest/TestDecodersPerf.cpp159
-rw-r--r--image/test/gtest/TestDeinterlacingFilter.cpp636
-rw-r--r--image/test/gtest/TestDownscalingFilter.cpp231
-rw-r--r--image/test/gtest/TestFrameAnimator.cpp130
-rw-r--r--image/test/gtest/TestLoader.cpp118
-rw-r--r--image/test/gtest/TestMetadata.cpp260
-rw-r--r--image/test/gtest/TestRemoveFrameRectFilter.cpp311
-rw-r--r--image/test/gtest/TestSourceBuffer.cpp822
-rw-r--r--image/test/gtest/TestStreamingLexer.cpp935
-rw-r--r--image/test/gtest/TestSurfaceCache.cpp159
-rw-r--r--image/test/gtest/TestSurfacePipeIntegration.cpp349
-rw-r--r--image/test/gtest/TestSurfaceSink.cpp982
-rw-r--r--image/test/gtest/TestSwizzleFilter.cpp120
-rw-r--r--image/test/gtest/animated-with-extra-image-sub-blocks.gifbin0 -> 434 bytes
-rw-r--r--image/test/gtest/blend.avifbin0 -> 1989 bytes
-rw-r--r--image/test/gtest/blend.gifbin0 -> 412 bytes
-rw-r--r--image/test/gtest/blend.pngbin0 -> 339 bytes
-rw-r--r--image/test/gtest/blend.webpbin0 -> 160 bytes
-rw-r--r--image/test/gtest/bug-1655846.avifbin0 -> 256 bytes
-rw-r--r--image/test/gtest/corrupt-with-bad-bmp-height.icobin0 -> 41663 bytes
-rw-r--r--image/test/gtest/corrupt-with-bad-bmp-width.icobin0 -> 41663 bytes
-rw-r--r--image/test/gtest/corrupt-with-bad-ico-bpp.icobin0 -> 3270 bytes
-rw-r--r--image/test/gtest/corrupt.jpgbin0 -> 2477 bytes
-rw-r--r--image/test/gtest/downscaled.avifbin0 -> 862 bytes
-rw-r--r--image/test/gtest/downscaled.bmpbin0 -> 30138 bytes
-rw-r--r--image/test/gtest/downscaled.gifbin0 -> 223 bytes
-rw-r--r--image/test/gtest/downscaled.icobin0 -> 41662 bytes
-rw-r--r--image/test/gtest/downscaled.iconbin0 -> 40005 bytes
-rw-r--r--image/test/gtest/downscaled.jpgbin0 -> 6035 bytes
-rw-r--r--image/test/gtest/downscaled.jxlbin0 -> 599 bytes
-rw-r--r--image/test/gtest/downscaled.pngbin0 -> 1015 bytes
-rw-r--r--image/test/gtest/downscaled.webpbin0 -> 56 bytes
-rw-r--r--image/test/gtest/exif_resolution.jpgbin0 -> 2018 bytes
-rw-r--r--image/test/gtest/first-frame-green.avifbin0 -> 1001 bytes
-rw-r--r--image/test/gtest/first-frame-green.gifbin0 -> 317 bytes
-rw-r--r--image/test/gtest/first-frame-green.pngbin0 -> 364 bytes
-rw-r--r--image/test/gtest/first-frame-green.webpbin0 -> 154 bytes
-rw-r--r--image/test/gtest/first-frame-padding.gifbin0 -> 49 bytes
-rw-r--r--image/test/gtest/gray-235-10bit-full-range-bt2020.avifbin0 -> 310 bytes
-rw-r--r--image/test/gtest/gray-235-10bit-full-range-bt601.avifbin0 -> 310 bytes
-rw-r--r--image/test/gtest/gray-235-10bit-full-range-bt709.avifbin0 -> 310 bytes
-rw-r--r--image/test/gtest/gray-235-10bit-full-range-grayscale.avifbin0 -> 301 bytes
-rw-r--r--image/test/gtest/gray-235-10bit-limited-range-bt2020.avifbin0 -> 310 bytes
-rw-r--r--image/test/gtest/gray-235-10bit-limited-range-bt601.avifbin0 -> 310 bytes
-rw-r--r--image/test/gtest/gray-235-10bit-limited-range-bt709.avifbin0 -> 310 bytes
-rw-r--r--image/test/gtest/gray-235-10bit-limited-range-grayscale.avifbin0 -> 301 bytes
-rw-r--r--image/test/gtest/gray-235-12bit-full-range-bt2020.avifbin0 -> 307 bytes
-rw-r--r--image/test/gtest/gray-235-12bit-full-range-bt601.avifbin0 -> 307 bytes
-rw-r--r--image/test/gtest/gray-235-12bit-full-range-bt709.avifbin0 -> 307 bytes
-rw-r--r--image/test/gtest/gray-235-12bit-full-range-grayscale.avifbin0 -> 301 bytes
-rw-r--r--image/test/gtest/gray-235-12bit-limited-range-bt2020.avifbin0 -> 307 bytes
-rw-r--r--image/test/gtest/gray-235-12bit-limited-range-bt601.avifbin0 -> 307 bytes
-rw-r--r--image/test/gtest/gray-235-12bit-limited-range-bt709.avifbin0 -> 307 bytes
-rw-r--r--image/test/gtest/gray-235-12bit-limited-range-grayscale.avifbin0 -> 301 bytes
-rw-r--r--image/test/gtest/gray-235-8bit-full-range-bt2020.avifbin0 -> 309 bytes
-rw-r--r--image/test/gtest/gray-235-8bit-full-range-bt601.avifbin0 -> 309 bytes
-rw-r--r--image/test/gtest/gray-235-8bit-full-range-bt709.avifbin0 -> 309 bytes
-rw-r--r--image/test/gtest/gray-235-8bit-full-range-grayscale.avifbin0 -> 300 bytes
-rw-r--r--image/test/gtest/gray-235-8bit-limited-range-bt2020.avifbin0 -> 309 bytes
-rw-r--r--image/test/gtest/gray-235-8bit-limited-range-bt601.avifbin0 -> 309 bytes
-rw-r--r--image/test/gtest/gray-235-8bit-limited-range-bt709.avifbin0 -> 309 bytes
-rw-r--r--image/test/gtest/gray-235-8bit-limited-range-grayscale.avifbin0 -> 300 bytes
-rw-r--r--image/test/gtest/green-1x1-truncated.gifbin0 -> 53 bytes
-rw-r--r--image/test/gtest/green-large-bmp.icobin0 -> 270398 bytes
-rw-r--r--image/test/gtest/green-large-png.icobin0 -> 341 bytes
-rw-r--r--image/test/gtest/green-multiple-sizes.icobin0 -> 14144 bytes
-rw-r--r--image/test/gtest/green.avifbin0 -> 321 bytes
-rw-r--r--image/test/gtest/green.bmpbin0 -> 30138 bytes
-rw-r--r--image/test/gtest/green.gifbin0 -> 156 bytes
-rw-r--r--image/test/gtest/green.icc_srgb.webpbin0 -> 3092 bytes
-rw-r--r--image/test/gtest/green.icobin0 -> 41662 bytes
-rw-r--r--image/test/gtest/green.iconbin0 -> 40004 bytes
-rw-r--r--image/test/gtest/green.jpgbin0 -> 361 bytes
-rw-r--r--image/test/gtest/green.jxlbin0 -> 33 bytes
-rw-r--r--image/test/gtest/green.pngbin0 -> 255 bytes
-rw-r--r--image/test/gtest/green.webpbin0 -> 42 bytes
-rw-r--r--image/test/gtest/hdlr-nonzero-reserved-bug-1727033.avifbin0 -> 294 bytes
-rw-r--r--image/test/gtest/invalid-truncated-metadata.bmpbin0 -> 54 bytes
-rw-r--r--image/test/gtest/large.avifbin0 -> 81500 bytes
-rw-r--r--image/test/gtest/large.jxlbin0 -> 315715 bytes
-rw-r--r--image/test/gtest/large.webpbin0 -> 168686 bytes
-rw-r--r--image/test/gtest/moz.build156
-rw-r--r--image/test/gtest/multilayer.avifbin0 -> 64613 bytes
-rw-r--r--image/test/gtest/no-frame-delay.gifbin0 -> 317 bytes
-rw-r--r--image/test/gtest/perf_cmyk.jpgbin0 -> 18960 bytes
-rw-r--r--image/test/gtest/perf_gray.jpgbin0 -> 4479 bytes
-rw-r--r--image/test/gtest/perf_gray.pngbin0 -> 4472 bytes
-rw-r--r--image/test/gtest/perf_gray_alpha.pngbin0 -> 6847 bytes
-rw-r--r--image/test/gtest/perf_srgb.gifbin0 -> 1743 bytes
-rw-r--r--image/test/gtest/perf_srgb.pngbin0 -> 2993 bytes
-rw-r--r--image/test/gtest/perf_srgb_alpha.pngbin0 -> 3203 bytes
-rw-r--r--image/test/gtest/perf_srgb_alpha_lossless.webpbin0 -> 3134 bytes
-rw-r--r--image/test/gtest/perf_srgb_alpha_lossy.webpbin0 -> 5014 bytes
-rw-r--r--image/test/gtest/perf_srgb_lossless.webpbin0 -> 3134 bytes
-rw-r--r--image/test/gtest/perf_srgb_lossy.webpbin0 -> 4948 bytes
-rw-r--r--image/test/gtest/perf_ycbcr.jpgbin0 -> 15049 bytes
-rw-r--r--image/test/gtest/rle4.bmpbin0 -> 3686 bytes
-rw-r--r--image/test/gtest/rle8.bmpbin0 -> 1288 bytes
-rw-r--r--image/test/gtest/stackcheck.avifbin0 -> 194817 bytes
-rw-r--r--image/test/gtest/transparent-green-50pct-10bit-yuv420.avifbin0 -> 556 bytes
-rw-r--r--image/test/gtest/transparent-green-50pct-10bit-yuv422.avifbin0 -> 551 bytes
-rw-r--r--image/test/gtest/transparent-green-50pct-10bit-yuv444.avifbin0 -> 556 bytes
-rw-r--r--image/test/gtest/transparent-green-50pct-12bit-yuv420.avifbin0 -> 556 bytes
-rw-r--r--image/test/gtest/transparent-green-50pct-12bit-yuv422.avifbin0 -> 557 bytes
-rw-r--r--image/test/gtest/transparent-green-50pct-12bit-yuv444.avifbin0 -> 558 bytes
-rw-r--r--image/test/gtest/transparent-green-50pct-8bit-yuv420.avifbin0 -> 539 bytes
-rw-r--r--image/test/gtest/transparent-green-50pct-8bit-yuv422.avifbin0 -> 533 bytes
-rw-r--r--image/test/gtest/transparent-green-50pct-8bit-yuv444.avifbin0 -> 537 bytes
-rw-r--r--image/test/gtest/transparent-ico-with-and-mask.icobin0 -> 3262 bytes
-rw-r--r--image/test/gtest/transparent-if-within-ico.bmpbin0 -> 4234 bytes
-rw-r--r--image/test/gtest/transparent-no-alpha-header.webpbin0 -> 120 bytes
-rw-r--r--image/test/gtest/transparent.avifbin0 -> 209480 bytes
-rw-r--r--image/test/gtest/transparent.gifbin0 -> 355 bytes
-rw-r--r--image/test/gtest/transparent.jxlbin0 -> 63244 bytes
-rw-r--r--image/test/gtest/transparent.pngbin0 -> 419 bytes
-rw-r--r--image/test/gtest/transparent.webpbin0 -> 120 bytes
-rw-r--r--image/test/gtest/valid-avif-colr-nclx-and-prof.avifbin0 -> 883 bytes
-rw-r--r--image/test/mochitest/12M-pixels-1.pngbin0 -> 22467 bytes
-rw-r--r--image/test/mochitest/12M-pixels-2.pngbin0 -> 22467 bytes
-rw-r--r--image/test/mochitest/6M-pixels.pngbin0 -> 10147 bytes
-rw-r--r--image/test/mochitest/INT32_MIN.bmpbin0 -> 60 bytes
-rw-r--r--image/test/mochitest/animated-avif.avifbin0 -> 1333 bytes
-rw-r--r--image/test/mochitest/animated-gif-finalframe.gifbin0 -> 72 bytes
-rw-r--r--image/test/mochitest/animated-gif.gifbin0 -> 146 bytes
-rw-r--r--image/test/mochitest/animated-gif2.gifbin0 -> 165 bytes
-rw-r--r--image/test/mochitest/animated-gif_trailing-garbage.gifbin0 -> 4030 bytes
-rw-r--r--image/test/mochitest/animated1.gifbin0 -> 4558 bytes
-rw-r--r--image/test/mochitest/animated1.svg12
-rw-r--r--image/test/mochitest/animated2.gifbin0 -> 4558 bytes
-rw-r--r--image/test/mochitest/animatedMask.gifbin0 -> 4568 bytes
-rw-r--r--image/test/mochitest/animation.svg5
-rw-r--r--image/test/mochitest/animationPolling.js469
-rw-r--r--image/test/mochitest/bad.jpgbin0 -> 2477 bytes
-rw-r--r--image/test/mochitest/big.pngbin0 -> 129497 bytes
-rw-r--r--image/test/mochitest/blue.gifbin0 -> 45 bytes
-rw-r--r--image/test/mochitest/blue.pngbin0 -> 2745 bytes
-rw-r--r--image/test/mochitest/bug1132427.gifbin0 -> 634 bytes
-rw-r--r--image/test/mochitest/bug1132427.html6
-rw-r--r--image/test/mochitest/bug1180105-waiter.sjs29
-rw-r--r--image/test/mochitest/bug1180105.sjs68
-rw-r--r--image/test/mochitest/bug1217571-iframe.html17
-rw-r--r--image/test/mochitest/bug1217571.jpgbin0 -> 2679 bytes
-rw-r--r--image/test/mochitest/bug1319025-ref.pngbin0 -> 347 bytes
-rw-r--r--image/test/mochitest/bug1319025.pngbin0 -> 422 bytes
-rw-r--r--image/test/mochitest/bug399925.gifbin0 -> 1645 bytes
-rw-r--r--image/test/mochitest/bug415761.icobin0 -> 766 bytes
-rw-r--r--image/test/mochitest/bug468160.sjs5
-rw-r--r--image/test/mochitest/bug478398_ONLY.pngbin0 -> 14139 bytes
-rw-r--r--image/test/mochitest/bug490949-iframe.html7
-rw-r--r--image/test/mochitest/bug490949.sjs32
-rw-r--r--image/test/mochitest/bug496292-1.sjs31
-rw-r--r--image/test/mochitest/bug496292-2.sjs31
-rw-r--r--image/test/mochitest/bug496292-iframe-1.html7
-rw-r--r--image/test/mochitest/bug496292-iframe-2.html7
-rw-r--r--image/test/mochitest/bug496292-iframe-ref.html7
-rw-r--r--image/test/mochitest/bug497665-iframe.html8
-rw-r--r--image/test/mochitest/bug497665.sjs33
-rw-r--r--image/test/mochitest/bug552605.sjs12
-rw-r--r--image/test/mochitest/bug657191.sjs26
-rw-r--r--image/test/mochitest/bug671906-iframe.html7
-rw-r--r--image/test/mochitest/bug671906.sjs34
-rw-r--r--image/test/mochitest/bug733553-informant.sjs13
-rw-r--r--image/test/mochitest/bug733553.sjs104
-rw-r--r--image/test/mochitest/bug767779.sjs56
-rw-r--r--image/test/mochitest/bug89419-iframe.html7
-rw-r--r--image/test/mochitest/bug89419.sjs12
-rw-r--r--image/test/mochitest/bug900200-ref.pngbin0 -> 660 bytes
-rw-r--r--image/test/mochitest/bug900200.pngbin0 -> 840 bytes
-rw-r--r--image/test/mochitest/child.html22
-rw-r--r--image/test/mochitest/chrome.ini7
-rw-r--r--image/test/mochitest/clear.avifbin0 -> 1975 bytes
-rw-r--r--image/test/mochitest/clear.gifbin0 -> 321 bytes
-rw-r--r--image/test/mochitest/clear.pngbin0 -> 622 bytes
-rw-r--r--image/test/mochitest/clear.webpbin0 -> 202 bytes
-rw-r--r--image/test/mochitest/clear2-results.gifbin0 -> 177 bytes
-rw-r--r--image/test/mochitest/clear2.gifbin0 -> 219 bytes
-rw-r--r--image/test/mochitest/clear2.webpbin0 -> 228 bytes
-rw-r--r--image/test/mochitest/damon.jpgbin0 -> 2679 bytes
-rw-r--r--image/test/mochitest/error-early.png1
-rw-r--r--image/test/mochitest/filter-final.svg9
-rw-r--r--image/test/mochitest/filter.svg9
-rw-r--r--image/test/mochitest/finite-apng.pngbin0 -> 5834 bytes
-rw-r--r--image/test/mochitest/first-frame-padding.gifbin0 -> 49 bytes
-rw-r--r--image/test/mochitest/green-background.html30
-rw-r--r--image/test/mochitest/green.pngbin0 -> 255 bytes
-rw-r--r--image/test/mochitest/grey.pngbin0 -> 256 bytes
-rw-r--r--image/test/mochitest/ico-bmp-opaque.icobin0 -> 1094 bytes
-rw-r--r--image/test/mochitest/ico-bmp-transparent.icobin0 -> 4286 bytes
-rw-r--r--image/test/mochitest/iframe.html5
-rw-r--r--image/test/mochitest/imgutils.js137
-rw-r--r--image/test/mochitest/infinite-apng.pngbin0 -> 1169 bytes
-rw-r--r--image/test/mochitest/infinite.avifbin0 -> 2311 bytes
-rw-r--r--image/test/mochitest/infinite.webpbin0 -> 3742 bytes
-rw-r--r--image/test/mochitest/invalid.jpg1
-rw-r--r--image/test/mochitest/keep.gifbin0 -> 321 bytes
-rw-r--r--image/test/mochitest/keep.pngbin0 -> 622 bytes
-rw-r--r--image/test/mochitest/keep.webpbin0 -> 152 bytes
-rw-r--r--image/test/mochitest/lime-anim-100x100-2.svg6
-rw-r--r--image/test/mochitest/lime-anim-100x100.svg7
-rw-r--r--image/test/mochitest/lime-css-anim-100x100.svg19
-rw-r--r--image/test/mochitest/lime100x100.svg4
-rw-r--r--image/test/mochitest/mochitest.ini184
-rw-r--r--image/test/mochitest/mq_dynamic_svg_ref.html38
-rw-r--r--image/test/mochitest/mq_dynamic_svg_test.html61
-rw-r--r--image/test/mochitest/opaque.bmpbin0 -> 1086 bytes
-rw-r--r--image/test/mochitest/over.pngbin0 -> 525 bytes
-rw-r--r--image/test/mochitest/purple.gifbin0 -> 86 bytes
-rw-r--r--image/test/mochitest/rainbow.gifbin0 -> 1572 bytes
-rw-r--r--image/test/mochitest/red.gifbin0 -> 43 bytes
-rw-r--r--image/test/mochitest/red.pngbin0 -> 82 bytes
-rw-r--r--image/test/mochitest/ref-iframe.html6
-rw-r--r--image/test/mochitest/restore-previous.gifbin0 -> 457 bytes
-rw-r--r--image/test/mochitest/restore-previous.pngbin0 -> 622 bytes
-rw-r--r--image/test/mochitest/rillybad.jpgbin0 -> 11142 bytes
-rw-r--r--image/test/mochitest/schrep.pngbin0 -> 38767 bytes
-rw-r--r--image/test/mochitest/shaver.pngbin0 -> 52045 bytes
-rw-r--r--image/test/mochitest/short_header.gifbin0 -> 1488 bytes
-rw-r--r--image/test/mochitest/source.pngbin0 -> 525 bytes
-rw-r--r--image/test/mochitest/test_animSVGImage.html124
-rw-r--r--image/test/mochitest/test_animSVGImage2.html124
-rw-r--r--image/test/mochitest/test_animated_css_image.html223
-rw-r--r--image/test/mochitest/test_animated_gif.html50
-rw-r--r--image/test/mochitest/test_animation.html45
-rw-r--r--image/test/mochitest/test_animation2.html49
-rw-r--r--image/test/mochitest/test_animation_operators.html168
-rw-r--r--image/test/mochitest/test_background_image_anim.html44
-rw-r--r--image/test/mochitest/test_bug1132427.html94
-rw-r--r--image/test/mochitest/test_bug1180105.html46
-rw-r--r--image/test/mochitest/test_bug1217571.html43
-rw-r--r--image/test/mochitest/test_bug1325080.html37
-rw-r--r--image/test/mochitest/test_bug399925.html102
-rw-r--r--image/test/mochitest/test_bug415761.html117
-rw-r--r--image/test/mochitest/test_bug435296.html85
-rw-r--r--image/test/mochitest/test_bug466586.html58
-rw-r--r--image/test/mochitest/test_bug468160.html29
-rw-r--r--image/test/mochitest/test_bug478398.html87
-rw-r--r--image/test/mochitest/test_bug490949.html112
-rw-r--r--image/test/mochitest/test_bug496292.html130
-rw-r--r--image/test/mochitest/test_bug497665.html88
-rw-r--r--image/test/mochitest/test_bug552605-1.html56
-rw-r--r--image/test/mochitest/test_bug552605-2.html53
-rw-r--r--image/test/mochitest/test_bug553982.html39
-rw-r--r--image/test/mochitest/test_bug601470.html45
-rw-r--r--image/test/mochitest/test_bug614392.html42
-rw-r--r--image/test/mochitest/test_bug657191.html34
-rw-r--r--image/test/mochitest/test_bug671906.html71
-rw-r--r--image/test/mochitest/test_bug733553.html92
-rw-r--r--image/test/mochitest/test_bug767779.html44
-rw-r--r--image/test/mochitest/test_bug865919.html53
-rw-r--r--image/test/mochitest/test_bug89419-1.html68
-rw-r--r--image/test/mochitest/test_bug89419-2.html70
-rw-r--r--image/test/mochitest/test_bullet_animation.html59
-rw-r--r--image/test/mochitest/test_canvas_frame_animation.html24
-rw-r--r--image/test/mochitest/test_changeOfSource.html62
-rw-r--r--image/test/mochitest/test_changeOfSource2.html47
-rw-r--r--image/test/mochitest/test_discardAnimatedImage.html218
-rw-r--r--image/test/mochitest/test_discardFinishedAnimatedImage.html144
-rw-r--r--image/test/mochitest/test_discardFramesAnimatedImage.html268
-rw-r--r--image/test/mochitest/test_drawDiscardedImage.html85
-rw-r--r--image/test/mochitest/test_error_events.html67
-rw-r--r--image/test/mochitest/test_has_transparency.html169
-rw-r--r--image/test/mochitest/test_image_cache_notification.html47
-rw-r--r--image/test/mochitest/test_image_crossorigin_data_url.html28
-rw-r--r--image/test/mochitest/test_mq_dynamic_svg.html49
-rw-r--r--image/test/mochitest/test_net_failedtoprocess.html52
-rw-r--r--image/test/mochitest/test_removal_ondecode.html160
-rw-r--r--image/test/mochitest/test_removal_onload.html142
-rw-r--r--image/test/mochitest/test_short_gif_header.html35
-rw-r--r--image/test/mochitest/test_staticClone.html41
-rw-r--r--image/test/mochitest/test_svg_animatedGIF.html53
-rw-r--r--image/test/mochitest/test_svg_filter_animation.html42
-rw-r--r--image/test/mochitest/test_synchronized_animation.html128
-rw-r--r--image/test/mochitest/test_undisplayed_iframe.html47
-rw-r--r--image/test/mochitest/test_webcam.html68
-rw-r--r--image/test/mochitest/test_xultree_animation.xhtml67
-rw-r--r--image/test/mochitest/transparent.gifbin0 -> 355 bytes
-rw-r--r--image/test/mochitest/transparent.pngbin0 -> 419 bytes
-rw-r--r--image/test/mochitest/webcam-simulacrum.sjs51
-rw-r--r--image/test/reftest/ImageDocument.css16
-rw-r--r--image/test/reftest/apng/bug411852-1-ref.html6
-rw-r--r--image/test/reftest/apng/bug411852-1-ref.pngbin0 -> 164 bytes
-rw-r--r--image/test/reftest/apng/bug411852-1.pngbin0 -> 606 bytes
-rw-r--r--image/test/reftest/apng/bug546272-ref.html6
-rw-r--r--image/test/reftest/apng/bug546272-ref.pngbin0 -> 712 bytes
-rw-r--r--image/test/reftest/apng/bug546272.pngbin0 -> 1391 bytes
-rw-r--r--image/test/reftest/apng/delaytest.html58
-rw-r--r--image/test/reftest/apng/reftest.list6
-rw-r--r--image/test/reftest/avif/1-normal.avifbin0 -> 370 bytes
-rw-r--r--image/test/reftest/avif/2-flipped-horizontally.avifbin0 -> 352 bytes
-rw-r--r--image/test/reftest/avif/3-rotated-180deg.avifbin0 -> 367 bytes
-rw-r--r--image/test/reftest/avif/4-flipped-vertically.avifbin0 -> 359 bytes
-rw-r--r--image/test/reftest/avif/5-rotated-90deg-CCW-and-flipped-vertically.avifbin0 -> 368 bytes
-rw-r--r--image/test/reftest/avif/6-rotated-90deg-CCW.avifbin0 -> 354 bytes
-rw-r--r--image/test/reftest/avif/7-rotated-90deg-CW-and-flipped-vertically.avifbin0 -> 361 bytes
-rw-r--r--image/test/reftest/avif/8-rotated-90deg-CW.avifbin0 -> 359 bytes
-rw-r--r--image/test/reftest/avif/img_irot0_imir0.avifbin0 -> 390 bytes
-rw-r--r--image/test/reftest/avif/img_irot0_imir1.avifbin0 -> 390 bytes
-rw-r--r--image/test/reftest/avif/img_irot0_imirN.avifbin0 -> 380 bytes
-rw-r--r--image/test/reftest/avif/img_irot1_imir0.avifbin0 -> 390 bytes
-rw-r--r--image/test/reftest/avif/img_irot1_imir1.avifbin0 -> 390 bytes
-rw-r--r--image/test/reftest/avif/img_irot1_imirN.avifbin0 -> 380 bytes
-rw-r--r--image/test/reftest/avif/img_irot2_imir0.avifbin0 -> 390 bytes
-rw-r--r--image/test/reftest/avif/img_irot2_imir1.avifbin0 -> 390 bytes
-rw-r--r--image/test/reftest/avif/img_irot2_imirN.avifbin0 -> 380 bytes
-rw-r--r--image/test/reftest/avif/img_irot3_imir0.avifbin0 -> 390 bytes
-rw-r--r--image/test/reftest/avif/img_irot3_imir1.avifbin0 -> 390 bytes
-rw-r--r--image/test/reftest/avif/img_irot3_imirN.avifbin0 -> 380 bytes
-rw-r--r--image/test/reftest/avif/img_irotN_imir0.avifbin0 -> 380 bytes
-rw-r--r--image/test/reftest/avif/img_irotN_imir1.avifbin0 -> 380 bytes
-rw-r--r--image/test/reftest/avif/img_irotN_imirN.avifbin0 -> 370 bytes
-rw-r--r--image/test/reftest/avif/reftest.list17
-rw-r--r--image/test/reftest/bmp/1240629-1.bmpbin0 -> 68 bytes
-rw-r--r--image/test/reftest/bmp/1240629-2.bmpbin0 -> 68 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-not-square-1bpp.bmpbin0 -> 130 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-not-square-1bpp.pngbin0 -> 147 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-15x15-1bpp.bmpbin0 -> 122 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-15x15-1bpp.pngbin0 -> 220 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-16x16-1bpp.bmpbin0 -> 126 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-16x16-1bpp.pngbin0 -> 242 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-17x17-1bpp.bmpbin0 -> 130 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-17x17-1bpp.pngbin0 -> 247 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-1x1-1bpp.bmpbin0 -> 66 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-1x1-1bpp.icobin0 -> 78 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-1x1-1bpp.pngbin0 -> 120 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-2x2-1bpp.bmpbin0 -> 70 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-2x2-1bpp.pngbin0 -> 126 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-31x31-1bpp.bmpbin0 -> 186 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-31x31-1bpp.pngbin0 -> 447 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-32x32-1bpp.bmpbin0 -> 190 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-32x32-1bpp.pngbin0 -> 455 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-33x33-1bpp.bmpbin0 -> 326 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-33x33-1bpp.pngbin0 -> 489 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-3x3-1bpp.bmpbin0 -> 74 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-3x3-1bpp.pngbin0 -> 132 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-4x4-1bpp.bmpbin0 -> 78 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-4x4-1bpp.pngbin0 -> 135 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-5x5-1bpp.bmpbin0 -> 82 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-5x5-1bpp.pngbin0 -> 146 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-6x6-1bpp.bmpbin0 -> 86 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-6x6-1bpp.pngbin0 -> 149 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-7x7-1bpp.bmpbin0 -> 90 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-7x7-1bpp.pngbin0 -> 156 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-8x8-1bpp.bmpbin0 -> 94 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-8x8-1bpp.pngbin0 -> 161 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-9x9-1bpp.bmpbin0 -> 98 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/bmp-size-9x9-1bpp.pngbin0 -> 171 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/os2bmp-size-32x32-1bpp.bmpbin0 -> 160 bytes
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/reftest.list21
-rw-r--r--image/test/reftest/bmp/bmp-1bpp/top-to-bottom-16x16-1bpp.bmpbin0 -> 126 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-not-square-24bpp.bmpbin0 -> 802 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-not-square-24bpp.pngbin0 -> 490 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-15x15-24bpp.bmpbin0 -> 774 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-15x15-24bpp.pngbin0 -> 809 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-16x16-24bpp.bmpbin0 -> 822 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-16x16-24bpp.pngbin0 -> 879 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-17x17-24bpp.bmpbin0 -> 938 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-17x17-24bpp.pngbin0 -> 1000 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-1x1-24bpp.bmpbin0 -> 58 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-1x1-24bpp.pngbin0 -> 70 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-2x2-24bpp.bmpbin0 -> 70 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-2x2-24bpp.pngbin0 -> 83 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-31x31-24bpp.bmpbin0 -> 3030 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-31x31-24bpp.pngbin0 -> 2936 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-32x32-24bpp.bmpbin0 -> 3126 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-32x32-24bpp.pngbin0 -> 3106 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-33x33-24bpp.bmpbin0 -> 3354 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-33x33-24bpp.pngbin0 -> 3303 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-3x3-24bpp.bmpbin0 -> 90 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-3x3-24bpp.pngbin0 -> 107 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-4x4-24bpp.bmpbin0 -> 102 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-4x4-24bpp.pngbin0 -> 136 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-5x5-24bpp.bmpbin0 -> 134 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-5x5-24bpp.pngbin0 -> 173 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-6x6-24bpp.bmpbin0 -> 174 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-6x6-24bpp.pngbin0 -> 218 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-7x7-24bpp.bmpbin0 -> 222 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-7x7-24bpp.pngbin0 -> 271 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-8x8-24bpp.bmpbin0 -> 246 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-8x8-24bpp.pngbin0 -> 313 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-9x9-24bpp.bmpbin0 -> 306 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/bmp-size-9x9-24bpp.pngbin0 -> 368 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/os2bmp-size-32x32-24bpp.bmpbin0 -> 3098 bytes
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/reftest.list21
-rw-r--r--image/test/reftest/bmp/bmp-24bpp/top-to-bottom-16x16-24bpp.bmpbin0 -> 822 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-not-square-4bpp.bmpbin0 -> 254 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-not-square-4bpp.pngbin0 -> 229 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-15x15-4bpp.bmpbin0 -> 238 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-15x15-4bpp.pngbin0 -> 304 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-16x16-4bpp.bmpbin0 -> 246 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-16x16-4bpp.pngbin0 -> 323 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-17x17-4bpp.bmpbin0 -> 322 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-17x17-4bpp.pngbin0 -> 337 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-1x1-4bpp.bmpbin0 -> 122 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-1x1-4bpp.pngbin0 -> 120 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-2x2-4bpp.bmpbin0 -> 126 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-2x2-4bpp.pngbin0 -> 128 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-31x31-4bpp.bmpbin0 -> 614 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-31x31-4bpp.pngbin0 -> 700 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-32x32-4bpp.bmpbin0 -> 630 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-32x32-4bpp.pngbin0 -> 763 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-33x33-4bpp.bmpbin0 -> 778 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-33x33-4bpp.pngbin0 -> 778 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-3x3-4bpp.bmpbin0 -> 130 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-3x3-4bpp.pngbin0 -> 139 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-4x4-4bpp.bmpbin0 -> 134 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-4x4-4bpp.pngbin0 -> 147 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-5x5-4bpp.bmpbin0 -> 138 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-5x5-4bpp.pngbin0 -> 156 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-6x6-4bpp.bmpbin0 -> 142 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-6x6-4bpp.pngbin0 -> 163 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-7x7-4bpp.bmpbin0 -> 146 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-7x7-4bpp.pngbin0 -> 172 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-8x8-4bpp.bmpbin0 -> 150 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-8x8-4bpp.pngbin0 -> 188 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-9x9-4bpp.bmpbin0 -> 190 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/bmp-size-9x9-4bpp.pngbin0 -> 198 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/os2bmp-size-32x32-4bpp.bmpbin0 -> 586 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/reftest.list24
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/rle4-delta-320x240.bmpbin0 -> 3686 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/rle4-delta-320x240.pngbin0 -> 886 bytes
-rw-r--r--image/test/reftest/bmp/bmp-4bpp/top-to-bottom-16x16-4bpp.bmpbin0 -> 246 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-extrapad-8bpp.pngbin0 -> 685 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-not-square-8bpp.bmpbin0 -> 1350 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-not-square-8bpp.pngbin0 -> 324 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-15x15-8bpp.bmpbin0 -> 1318 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-15x15-8bpp.pngbin0 -> 325 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-16x16-8bpp.bmpbin0 -> 1334 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-16x16-8bpp.pngbin0 -> 338 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-17x17-8bpp.bmpbin0 -> 1418 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-17x17-8bpp.pngbin0 -> 372 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-1x1-8bpp.bmpbin0 -> 1082 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-1x1-8bpp.pngbin0 -> 120 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-2x2-8bpp.bmpbin0 -> 1086 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-2x2-8bpp.pngbin0 -> 131 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-31x31-8bpp.bmpbin0 -> 2102 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-31x31-8bpp.pngbin0 -> 772 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-32x32-8bpp.bmpbin0 -> 2102 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-32x32-8bpp.pngbin0 -> 754 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-33x33-8bpp.bmpbin0 -> 2266 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-33x33-8bpp.pngbin0 -> 833 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-3x3-8bpp.bmpbin0 -> 1090 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-3x3-8bpp.pngbin0 -> 150 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-4x4-8bpp.bmpbin0 -> 1094 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-4x4-8bpp.pngbin0 -> 165 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-5x5-8bpp.bmpbin0 -> 1118 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-5x5-8bpp.pngbin0 -> 169 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-6x6-8bpp.bmpbin0 -> 1126 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-6x6-8bpp.pngbin0 -> 180 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-7x7-8bpp.bmpbin0 -> 1134 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-7x7-8bpp.pngbin0 -> 194 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-8x8-8bpp.bmpbin0 -> 1142 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-8x8-8bpp.pngbin0 -> 217 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-9x9-8bpp.bmpbin0 -> 1186 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/bmp-size-9x9-8bpp.pngbin0 -> 229 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/os2-bmp-size-32x32-8bpp.bmpbin0 -> 1818 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/reftest.list25
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/rle-bmp-extrapad-8bpp.bmpbin0 -> 1604 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/rle-bmp-not-square-8bpp.bmpbin0 -> 1384 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/rle-bmp-size-32x32-8bpp.bmpbin0 -> 1288 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/top-to-bottom-16x16-8bpp.bmpbin0 -> 1334 bytes
-rw-r--r--image/test/reftest/bmp/bmp-8bpp/top-to-bottom-rle-bmp-size-32x32-8bpp.bmpbin0 -> 1284 bytes
-rw-r--r--image/test/reftest/bmp/bmp-corrupted/invalid-bpp.bmpbin0 -> 58 bytes
-rw-r--r--image/test/reftest/bmp/bmp-corrupted/invalid-compression-BITFIELDS.bmpbin0 -> 78 bytes
-rw-r--r--image/test/reftest/bmp/bmp-corrupted/invalid-compression-RLE4.bmpbin0 -> 246 bytes
-rw-r--r--image/test/reftest/bmp/bmp-corrupted/invalid-compression-RLE8.bmpbin0 -> 246 bytes
-rw-r--r--image/test/reftest/bmp/bmp-corrupted/invalid-compression.bmpbin0 -> 822 bytes
-rw-r--r--image/test/reftest/bmp/bmp-corrupted/invalid-data-offset.bmpbin0 -> 3126 bytes
-rw-r--r--image/test/reftest/bmp/bmp-corrupted/invalid-signature.bmpbin0 -> 58 bytes
-rw-r--r--image/test/reftest/bmp/bmp-corrupted/invalid-truncated-metadata.bmpbin0 -> 54 bytes
-rw-r--r--image/test/reftest/bmp/bmp-corrupted/os2-invalid-bpp.bmpbin0 -> 30 bytes
-rw-r--r--image/test/reftest/bmp/bmp-corrupted/reftest.list21
-rw-r--r--image/test/reftest/bmp/bmp-corrupted/wrapper.html28
-rw-r--r--image/test/reftest/bmp/bmpsuite/COPYING.txt675
-rw-r--r--image/test/reftest/bmp/bmpsuite/README.mozilla40
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badbitcount.bmpbin0 -> 1086 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badbitssize.bmpbin0 -> 1086 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/baddens1.bmpbin0 -> 1086 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/baddens2.bmpbin0 -> 1086 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badfilesize.bmpbin0 -> 1086 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badheadersize.bmpbin0 -> 1112 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badpalettesize.bmpbin0 -> 9254 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badplanes.bmpbin0 -> 1086 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badrle.bmpbin0 -> 9212 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badrle.pngbin0 -> 438 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badrle4.bmpbin0 -> 4326 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badrle4.pngbin0 -> 245 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badrle4bis.bmpbin0 -> 4326 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badrle4bis.pngbin0 -> 880 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badrle4ter.bmpbin0 -> 4326 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badrle4ter.pngbin0 -> 883 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badrlebis.bmpbin0 -> 9212 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badrlebis.pngbin0 -> 1626 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badrleter.bmpbin0 -> 9212 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badrleter.pngbin0 -> 1628 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/badwidth.bmpbin0 -> 1086 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/pal1.pngbin0 -> 586 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/pal8.pngbin0 -> 3772 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/pal8badindex.bmpbin0 -> 8650 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/pal8badindex.pngbin0 -> 1819 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/reallybig.bmpbin0 -> 24630 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/reftest.list110
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/rgb16-880.bmpbin0 -> 16450 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/rgb16-880.pngbin0 -> 1029 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/rletopdown.bmpbin0 -> 8788 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/shortfile.bmpbin0 -> 273 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/shortfile.pngbin0 -> 399 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/b/wrapper.html28
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal1.bmpbin0 -> 1086 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal1.pngbin0 -> 586 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal1bg.bmpbin0 -> 1086 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal1bg.pngbin0 -> 604 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal1wb.bmpbin0 -> 1086 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal4.bmpbin0 -> 4198 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal4.pngbin0 -> 1428 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal4gs.bmpbin0 -> 4198 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal4gs.pngbin0 -> 2016 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal4rle.bmpbin0 -> 3836 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8-0.bmpbin0 -> 9270 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8.bmpbin0 -> 9254 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8.pngbin0 -> 3772 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8gs.bmpbin0 -> 9254 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8gs.pngbin0 -> 9441 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8nonsquare-e.pngbin0 -> 2513 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8nonsquare.bmpbin0 -> 5158 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8nonsquare.pngbin0 -> 2714 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8os2.bmpbin0 -> 8986 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8rle.bmpbin0 -> 8788 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8topdown.bmpbin0 -> 9254 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8v4.bmpbin0 -> 9322 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8v5.bmpbin0 -> 9338 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8w124.bmpbin0 -> 8626 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8w124.pngbin0 -> 3585 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8w125.bmpbin0 -> 8998 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8w125.pngbin0 -> 3628 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8w126.bmpbin0 -> 9126 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/pal8w126.pngbin0 -> 3714 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/reftest.list129
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/rgb16-565.bmpbin0 -> 16450 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/rgb16-565.pngbin0 -> 1297 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/rgb16-565pal.bmpbin0 -> 17474 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/rgb16.bmpbin0 -> 16438 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/rgb16.pngbin0 -> 1177 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/rgb16bfdef.bmpbin0 -> 16450 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/rgb24.bmpbin0 -> 24630 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/rgb24.pngbin0 -> 1072 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/rgb24pal.bmpbin0 -> 25654 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/rgb32.bmpbin0 -> 32566 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/rgb32bf.bmpbin0 -> 32578 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/g/rgb32bfdef.bmpbin0 -> 32578 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal1huff.bmpbin0 -> 2151 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal1p1.bmpbin0 -> 1082 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal1p1.pngbin0 -> 124 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal2.bmpbin0 -> 2118 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal2color.bmpbin0 -> 2118 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal4rlecut.bmpbin0 -> 3610 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal4rlecut.pngbin0 -> 1918 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal4rletrns.bmpbin0 -> 4326 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal4rletrns.pngbin0 -> 1465 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8.pngbin0 -> 3772 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8offs.bmpbin0 -> 9354 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8os2-hs.bmpbin0 -> 8986 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8os2-sz.bmpbin0 -> 8986 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8os2sp.bmpbin0 -> 8974 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8os2v2-16.bmpbin0 -> 9246 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8os2v2-40sz.bmpbin0 -> 9254 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8os2v2-sz.bmpbin0 -> 9278 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8os2v2.bmpbin0 -> 9278 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8oversizepal.bmpbin0 -> 9446 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8rlecut.bmpbin0 -> 7980 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8rlecut.pngbin0 -> 3524 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8rletrns.bmpbin0 -> 9212 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/pal8rletrns.pngbin0 -> 3793 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/reftest.list251
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb16-231.bmpbin0 -> 16450 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb16-231.pngbin0 -> 2643 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb16-3103.bmpbin0 -> 16450 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb16-3103.pngbin0 -> 3347 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb16.pngbin0 -> 1177 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb16faketrns.bmpbin0 -> 16438 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb24.pngbin0 -> 1072 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb24jpeg.bmpbin0 -> 2457 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb24largepal.bmpbin0 -> 25830 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb24lprof.bmpbin0 -> 24743 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb24png.bmpbin0 -> 1210 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb24prof.bmpbin0 -> 27782 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb24prof2.bmpbin0 -> 25254 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb24rle24.bmpbin0 -> 21432 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb32-111110.bmpbin0 -> 32578 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb32-7187.bmpbin0 -> 32578 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb32-7187.pngbin0 -> 2136 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb32-xbgr.bmpbin0 -> 32650 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb32fakealpha.bmpbin0 -> 32566 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgb32h52.bmpbin0 -> 32578 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba16-1924.bmpbin0 -> 16522 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba16-1924.pngbin0 -> 2811 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba16-4444.bmpbin0 -> 16522 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba16-4444.pngbin0 -> 1093 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba16-5551.bmpbin0 -> 16522 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba16-5551.pngbin0 -> 1226 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba32-1.bmpbin0 -> 32650 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba32-1010102.bmpbin0 -> 32650 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba32-1010102.pngbin0 -> 1253 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba32-2.bmpbin0 -> 32650 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba32-61754.bmpbin0 -> 32650 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba32-61754.pngbin0 -> 2483 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba32-81284.bmpbin0 -> 32650 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba32-81284.pngbin0 -> 2182 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba32.pngbin0 -> 1229 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba32abf.bmpbin0 -> 32582 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/rgba32h56.bmpbin0 -> 32582 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/q/wrapper.html28
-rw-r--r--image/test/reftest/bmp/bmpsuite/reftest.list8
-rw-r--r--image/test/reftest/bmp/bmpsuite/x/ba-bm.bmpbin0 -> 9000 bytes
-rw-r--r--image/test/reftest/bmp/bmpsuite/x/reftest.list10
-rw-r--r--image/test/reftest/bmp/bmpsuite/x/wrapper.html28
-rw-r--r--image/test/reftest/bmp/reftest.list16
-rw-r--r--image/test/reftest/color-management/color-curv.pngbin0 -> 1753 bytes
-rw-r--r--image/test/reftest/color-management/color-lin.pngbin0 -> 1749 bytes
-rw-r--r--image/test/reftest/color-management/color-table.pngbin0 -> 1754 bytes
-rw-r--r--image/test/reftest/color-management/invalid-chrm-ref.pngbin0 -> 1460 bytes
-rw-r--r--image/test/reftest/color-management/invalid-chrm.pngbin0 -> 1504 bytes
-rw-r--r--image/test/reftest/color-management/invalid-whitepoint.pngbin0 -> 1504 bytes
-rw-r--r--image/test/reftest/color-management/reftest.list7
-rw-r--r--image/test/reftest/color-management/trc-type-ref.html8
-rw-r--r--image/test/reftest/color-management/trc-type.html53
-rw-r--r--image/test/reftest/colordepth.html16
-rw-r--r--image/test/reftest/downscaling/100x100.gifbin0 -> 956 bytes
-rw-r--r--image/test/reftest/downscaling/100x100.jpgbin0 -> 917 bytes
-rw-r--r--image/test/reftest/downscaling/100x100.pngbin0 -> 338 bytes
-rw-r--r--image/test/reftest/downscaling/100x32768.gifbin0 -> 4299 bytes
-rw-r--r--image/test/reftest/downscaling/100x32768.jpgbin0 -> 22041 bytes
-rw-r--r--image/test/reftest/downscaling/100x32768.pngbin0 -> 70926 bytes
-rw-r--r--image/test/reftest/downscaling/1404366-1.html14
-rw-r--r--image/test/reftest/downscaling/1404366-1.icobin0 -> 4287 bytes
-rw-r--r--image/test/reftest/downscaling/1421191-1.html20
-rw-r--r--image/test/reftest/downscaling/1421191-1.pngbin0 -> 92182 bytes
-rw-r--r--image/test/reftest/downscaling/32768x100.gifbin0 -> 4299 bytes
-rw-r--r--image/test/reftest/downscaling/32768x100.jpgbin0 -> 58065 bytes
-rw-r--r--image/test/reftest/downscaling/32768x100.pngbin0 -> 13172 bytes
-rw-r--r--image/test/reftest/downscaling/black-border-bottom.pngbin0 -> 4094 bytes
-rw-r--r--image/test/reftest/downscaling/black-border-left.pngbin0 -> 4176 bytes
-rw-r--r--image/test/reftest/downscaling/black-border-rect.svg3
-rw-r--r--image/test/reftest/downscaling/black-border-right.pngbin0 -> 4097 bytes
-rw-r--r--image/test/reftest/downscaling/black-border-top.pngbin0 -> 4144 bytes
-rw-r--r--image/test/reftest/downscaling/bmp-size-16x16-24bpp.pngbin0 -> 879 bytes
-rw-r--r--image/test/reftest/downscaling/downscale-1-bigimage.pngbin0 -> 195 bytes
-rw-r--r--image/test/reftest/downscaling/downscale-1-ref.html8
-rw-r--r--image/test/reftest/downscaling/downscale-1-smallimage.pngbin0 -> 88 bytes
-rw-r--r--image/test/reftest/downscaling/downscale-1.html24
-rw-r--r--image/test/reftest/downscaling/downscale-16px.html28
-rw-r--r--image/test/reftest/downscaling/downscale-2a.html31
-rw-r--r--image/test/reftest/downscaling/downscale-2b.html31
-rw-r--r--image/test/reftest/downscaling/downscale-2c.html31
-rw-r--r--image/test/reftest/downscaling/downscale-2d.html31
-rw-r--r--image/test/reftest/downscaling/downscale-2e.html31
-rw-r--r--image/test/reftest/downscaling/downscale-2f.html31
-rw-r--r--image/test/reftest/downscaling/downscale-32px-ref.html8
-rw-r--r--image/test/reftest/downscaling/downscale-32px.html31
-rw-r--r--image/test/reftest/downscaling/downscale-8px.html27
-rw-r--r--image/test/reftest/downscaling/downscale-moz-icon-1-ref.html41
-rw-r--r--image/test/reftest/downscaling/downscale-moz-icon-1.html19
-rw-r--r--image/test/reftest/downscaling/downscale-orient-ref.html24
-rw-r--r--image/test/reftest/downscaling/downscale-orient-ref.pngbin0 -> 146 bytes
-rw-r--r--image/test/reftest/downscaling/downscale-orient.html24
-rw-r--r--image/test/reftest/downscaling/downscale-png.html31
-rw-r--r--image/test/reftest/downscaling/downscale-svg-1-ref.html13
-rw-r--r--image/test/reftest/downscaling/downscale-svg-1a.html8
-rw-r--r--image/test/reftest/downscaling/downscale-svg-1b.html8
-rw-r--r--image/test/reftest/downscaling/downscale-svg-1c.html8
-rw-r--r--image/test/reftest/downscaling/downscale-svg-1d.html8
-rw-r--r--image/test/reftest/downscaling/downscale-svg-1e.html8
-rw-r--r--image/test/reftest/downscaling/downscale-svg-1f.html8
-rw-r--r--image/test/reftest/downscaling/ff-0RGB.icobin0 -> 4286 bytes
-rw-r--r--image/test/reftest/downscaling/ff-0RGB.pngbin0 -> 2515 bytes
-rw-r--r--image/test/reftest/downscaling/ff-ARGB.icobin0 -> 4286 bytes
-rw-r--r--image/test/reftest/downscaling/ff-ARGB.pngbin0 -> 115 bytes
-rw-r--r--image/test/reftest/downscaling/huge-1.html9
-rw-r--r--image/test/reftest/downscaling/image-pre-rotated-90-deg.jpgbin0 -> 6914 bytes
-rw-r--r--image/test/reftest/downscaling/lime-red-256px-bmp-in.icobin0 -> 74814 bytes
-rw-r--r--image/test/reftest/downscaling/lime-red-256px-png-in.icobin0 -> 881 bytes
-rw-r--r--image/test/reftest/downscaling/lime-red-256px.bmpbin0 -> 196730 bytes
-rw-r--r--image/test/reftest/downscaling/lime-red-256px.gifbin0 -> 873 bytes
-rw-r--r--image/test/reftest/downscaling/lime-red-256px.jpgbin0 -> 2865 bytes
-rw-r--r--image/test/reftest/downscaling/lime-red-256px.pngbin0 -> 568 bytes
-rw-r--r--image/test/reftest/downscaling/lime-red-256px.svg5
-rw-r--r--image/test/reftest/downscaling/lime-red-32px.pngbin0 -> 103 bytes
-rw-r--r--image/test/reftest/downscaling/png-interlaced.pngbin0 -> 806 bytes
-rw-r--r--image/test/reftest/downscaling/png-normal.pngbin0 -> 421 bytes
-rw-r--r--image/test/reftest/downscaling/reftest.list217
-rw-r--r--image/test/reftest/downscaling/top-to-bottom-16x16-24bpp.bmpbin0 -> 822 bytes
-rw-r--r--image/test/reftest/encoders-lossless/ImageDocument.css16
-rw-r--r--image/test/reftest/encoders-lossless/encoder.html113
-rw-r--r--image/test/reftest/encoders-lossless/reftest.list175
-rw-r--r--image/test/reftest/encoders-lossless/size-15x15.pngbin0 -> 809 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-16x16.pngbin0 -> 879 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-17x17.pngbin0 -> 1000 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-1x1.pngbin0 -> 70 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-256x256.pngbin0 -> 5480 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-2x2.pngbin0 -> 83 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-31x31.pngbin0 -> 2936 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-32x32.pngbin0 -> 3106 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-33x33.pngbin0 -> 3303 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-3x3.pngbin0 -> 107 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-4x4.pngbin0 -> 136 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-5x5.pngbin0 -> 173 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-6x6.pngbin0 -> 218 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-7x7.pngbin0 -> 271 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-8x8.pngbin0 -> 313 bytes
-rw-r--r--image/test/reftest/encoders-lossless/size-9x9.pngbin0 -> 368 bytes
-rw-r--r--image/test/reftest/encoders-lossless/test.pngbin0 -> 3106 bytes
-rw-r--r--image/test/reftest/generic/accept-image-catchall-ref.html12
-rw-r--r--image/test/reftest/generic/accept-image-catchall.html13
-rw-r--r--image/test/reftest/generic/check-header.sjs72
-rw-r--r--image/test/reftest/generic/green.pngbin0 -> 201 bytes
-rw-r--r--image/test/reftest/generic/moz-icon-1.html1
-rw-r--r--image/test/reftest/generic/moz-icon-blank-1-almostref.html2
-rw-r--r--image/test/reftest/generic/moz-icon-blank-1-antiref.html2
-rw-r--r--image/test/reftest/generic/moz-icon-blank-1-antiref2.html2
-rw-r--r--image/test/reftest/generic/moz-icon-blank-1-ref.html2
-rw-r--r--image/test/reftest/generic/moz-icon-blank-1.html2
-rw-r--r--image/test/reftest/generic/reftest.list6
-rw-r--r--image/test/reftest/gif/1bit-255-trans.gifbin0 -> 337 bytes
-rw-r--r--image/test/reftest/gif/1bit-255-trans.pngbin0 -> 1214 bytes
-rw-r--r--image/test/reftest/gif/ImageDocument.css16
-rw-r--r--image/test/reftest/gif/animation1a.gifbin0 -> 167 bytes
-rw-r--r--image/test/reftest/gif/animation2a-finalframe.gifbin0 -> 107 bytes
-rw-r--r--image/test/reftest/gif/animation2a.gifbin0 -> 167 bytes
-rw-r--r--image/test/reftest/gif/blue.gifbin0 -> 43 bytes
-rw-r--r--image/test/reftest/gif/comment.gifbin0 -> 68 bytes
-rw-r--r--image/test/reftest/gif/comment.pngbin0 -> 167 bytes
-rw-r--r--image/test/reftest/gif/delaytest.html58
-rw-r--r--image/test/reftest/gif/in-colormap-trans.gifbin0 -> 355 bytes
-rw-r--r--image/test/reftest/gif/in-colormap-trans.pngbin0 -> 237 bytes
-rw-r--r--image/test/reftest/gif/one-color-offset-ref.gifbin0 -> 69 bytes
-rw-r--r--image/test/reftest/gif/one-color-offset.gifbin0 -> 49 bytes
-rw-r--r--image/test/reftest/gif/one-pixel-no-image-data-ref.html11
-rw-r--r--image/test/reftest/gif/one-pixel-no-image-data.html11
-rw-r--r--image/test/reftest/gif/out-of-colormap-trans.gifbin0 -> 355 bytes
-rw-r--r--image/test/reftest/gif/out-of-colormap-trans.pngbin0 -> 241 bytes
-rw-r--r--image/test/reftest/gif/red.gifbin0 -> 43 bytes
-rw-r--r--image/test/reftest/gif/reftest.list32
-rw-r--r--image/test/reftest/gif/small-background-size-2-ref.gifbin0 -> 807 bytes
-rw-r--r--image/test/reftest/gif/small-background-size-2.gifbin0 -> 572 bytes
-rw-r--r--image/test/reftest/gif/small-background-size-ref.gifbin0 -> 1076 bytes
-rw-r--r--image/test/reftest/gif/small-background-size.gifbin0 -> 991 bytes
-rw-r--r--image/test/reftest/gif/test_bug641198.html53
-rw-r--r--image/test/reftest/gif/tile-transform-ref.html12
-rw-r--r--image/test/reftest/gif/tile-transform.html12
-rw-r--r--image/test/reftest/gif/tiletest-ref.pngbin0 -> 282 bytes
-rw-r--r--image/test/reftest/gif/tiletest.gifbin0 -> 156 bytes
-rw-r--r--image/test/reftest/gif/transparent-animation-finalframe.gifbin0 -> 121 bytes
-rw-r--r--image/test/reftest/gif/transparent-animation-finalframe.html6
-rw-r--r--image/test/reftest/gif/transparent-animation.gifbin0 -> 527 bytes
-rw-r--r--image/test/reftest/gif/truncated-framerect-interlaced-ref.gifbin0 -> 927 bytes
-rw-r--r--image/test/reftest/gif/truncated-framerect-interlaced.gifbin0 -> 927 bytes
-rw-r--r--image/test/reftest/gif/truncated-framerect-ref.gifbin0 -> 929 bytes
-rw-r--r--image/test/reftest/gif/truncated-framerect-ref.html33
-rw-r--r--image/test/reftest/gif/truncated-framerect.gifbin0 -> 929 bytes
-rw-r--r--image/test/reftest/gif/truncated-framerect.html28
-rw-r--r--image/test/reftest/ico/cur/pointer.curbin0 -> 4286 bytes
-rw-r--r--image/test/reftest/ico/cur/pointer.pngbin0 -> 453 bytes
-rw-r--r--image/test/reftest/ico/cur/reftest.list4
-rw-r--r--image/test/reftest/ico/cur/wrapper.html28
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-not-square-transparent-1bpp.icobin0 -> 182 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-not-square-transparent-1bpp.pngbin0 -> 241 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-partial-transparent-1bpp.icobin0 -> 326 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-partial-transparent-1bpp.pngbin0 -> 410 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-15x15-1bpp.icobin0 -> 190 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-15x15-1bpp.pngbin0 -> 220 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-16x16-1bpp.icobin0 -> 198 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-16x16-1bpp.pngbin0 -> 242 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-17x17-1bpp.icobin0 -> 206 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-17x17-1bpp.pngbin0 -> 247 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-1x1-1bpp.icobin0 -> 78 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-1x1-1bpp.pngbin0 -> 120 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-256x256-1bpp.icobin0 -> 16454 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-256x256-1bpp.pngbin0 -> 7673 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-2x2-1bpp.icobin0 -> 86 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-2x2-1bpp.pngbin0 -> 126 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-31x31-1bpp.icobin0 -> 318 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-31x31-1bpp.pngbin0 -> 447 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-32x32-1bpp.icobin0 -> 326 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-32x32-1bpp.pngbin0 -> 455 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-33x33-1bpp.icobin0 -> 598 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-33x33-1bpp.pngbin0 -> 489 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-3x3-1bpp.icobin0 -> 94 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-3x3-1bpp.pngbin0 -> 132 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-4x4-1bpp.icobin0 -> 102 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-4x4-1bpp.pngbin0 -> 135 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-5x5-1bpp.icobin0 -> 110 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-5x5-1bpp.pngbin0 -> 146 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-6x6-1bpp.icobin0 -> 118 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-6x6-1bpp.pngbin0 -> 149 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-7x7-1bpp.icobin0 -> 126 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-7x7-1bpp.pngbin0 -> 156 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-8x8-1bpp.icobin0 -> 134 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-8x8-1bpp.pngbin0 -> 161 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-9x9-1bpp.icobin0 -> 142 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-size-9x9-1bpp.pngbin0 -> 171 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-transparent-1bpp.icobin0 -> 3262 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/ico-transparent-1bpp.pngbin0 -> 195 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-1bpp/reftest.list23
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-not-square-transparent-24bpp.icobin0 -> 1126 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-not-square-transparent-24bpp.pngbin0 -> 514 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-partial-transparent-24bpp.icobin0 -> 3262 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-partial-transparent-24bpp.pngbin0 -> 1028 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-15x15-24bpp.icobin0 -> 842 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-15x15-24bpp.pngbin0 -> 809 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-16x16-24bpp.icobin0 -> 894 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-16x16-24bpp.pngbin0 -> 879 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-17x17-24bpp.icobin0 -> 1014 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-17x17-24bpp.pngbin0 -> 1000 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-1x1-24bpp.icobin0 -> 70 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-1x1-24bpp.pngbin0 -> 70 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-256x256-24bpp.icobin0 -> 204862 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-256x256-24bpp.pngbin0 -> 5480 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-2x2-24bpp.icobin0 -> 86 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-2x2-24bpp.pngbin0 -> 83 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-31x31-24bpp.icobin0 -> 3162 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-31x31-24bpp.pngbin0 -> 2936 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-32x32-24bpp.icobin0 -> 3262 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-32x32-24bpp.pngbin0 -> 3106 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-33x33-24bpp.icobin0 -> 3626 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-33x33-24bpp.pngbin0 -> 3303 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-3x3-24bpp.icobin0 -> 110 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-3x3-24bpp.pngbin0 -> 107 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-4x4-24bpp.icobin0 -> 126 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-4x4-24bpp.pngbin0 -> 136 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-5x5-24bpp.icobin0 -> 162 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-5x5-24bpp.pngbin0 -> 173 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-6x6-24bpp.icobin0 -> 206 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-6x6-24bpp.pngbin0 -> 218 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-7x7-24bpp.icobin0 -> 258 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-7x7-24bpp.pngbin0 -> 271 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-8x8-24bpp.icobin0 -> 286 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-8x8-24bpp.pngbin0 -> 313 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-9x9-24bpp.icobin0 -> 350 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-size-9x9-24bpp.pngbin0 -> 368 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-transparent-24bpp.icobin0 -> 3262 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/ico-transparent-24bpp.pngbin0 -> 195 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-24bpp/reftest.list23
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-not-square-transparent-32bpp.icobin0 -> 1462 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-not-square-transparent-32bpp.pngbin0 -> 533 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-partial-transparent-32bpp.icobin0 -> 4286 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-partial-transparent-32bpp.pngbin0 -> 1028 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-15x15-32bpp.icobin0 -> 1022 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-15x15-32bpp.pngbin0 -> 809 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-16x16-32bpp.icobin0 -> 1150 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-16x16-32bpp.pngbin0 -> 879 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-17x17-32bpp.icobin0 -> 1286 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-17x17-32bpp.pngbin0 -> 1000 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-1x1-32bpp.icobin0 -> 70 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-1x1-32bpp.pngbin0 -> 70 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-256x256-32bpp.icobin0 -> 270398 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-256x256-32bpp.pngbin0 -> 5480 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-2x2-32bpp.icobin0 -> 86 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-2x2-32bpp.pngbin0 -> 83 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-31x31-32bpp.icobin0 -> 4030 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-31x31-32bpp.pngbin0 -> 2936 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-32x32-32bpp.icobin0 -> 4286 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-32x32-32bpp.pngbin0 -> 3106 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-33x33-32bpp.icobin0 -> 4682 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-33x33-32bpp.pngbin0 -> 3303 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-3x3-32bpp.icobin0 -> 110 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-3x3-32bpp.pngbin0 -> 107 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-4x4-32bpp.icobin0 -> 142 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-4x4-32bpp.pngbin0 -> 136 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-5x5-32bpp.icobin0 -> 182 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-5x5-32bpp.pngbin0 -> 173 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-6x6-32bpp.icobin0 -> 230 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-6x6-32bpp.pngbin0 -> 218 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-7x7-32bpp.icobin0 -> 286 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-7x7-32bpp.pngbin0 -> 271 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-8x8-32bpp.icobin0 -> 350 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-8x8-32bpp.pngbin0 -> 313 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-9x9-32bpp.icobin0 -> 422 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-size-9x9-32bpp.pngbin0 -> 368 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-transparent-32bpp.icobin0 -> 4286 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/ico-transparent-32bpp.pngbin0 -> 195 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-32bpp/reftest.list22
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-not-square-transparent-4bpp.icobin0 -> 350 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-not-square-transparent-4bpp.pngbin0 -> 315 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-partial-transparent-4bpp.icobin0 -> 766 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-partial-transparent-4bpp.pngbin0 -> 556 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-15x15-4bpp.icobin0 -> 306 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-15x15-4bpp.pngbin0 -> 304 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-16x16-4bpp.icobin0 -> 318 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-16x16-4bpp.pngbin0 -> 323 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-17x17-4bpp.icobin0 -> 398 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-17x17-4bpp.pngbin0 -> 337 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-1x1-4bpp.icobin0 -> 134 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-1x1-4bpp.pngbin0 -> 120 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-256x256-4bpp.icobin0 -> 41086 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-256x256-4bpp.pngbin0 -> 16944 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-2x2-4bpp.icobin0 -> 142 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-2x2-4bpp.pngbin0 -> 128 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-31x31-4bpp.icobin0 -> 746 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-31x31-4bpp.pngbin0 -> 700 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-32x32-4bpp.icobin0 -> 766 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-32x32-4bpp.pngbin0 -> 763 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-33x33-4bpp.icobin0 -> 1050 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-33x33-4bpp.pngbin0 -> 778 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-3x3-4bpp.icobin0 -> 150 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-3x3-4bpp.pngbin0 -> 139 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-4x4-4bpp.icobin0 -> 158 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-4x4-4bpp.pngbin0 -> 147 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-5x5-4bpp.icobin0 -> 166 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-5x5-4bpp.pngbin0 -> 156 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-6x6-4bpp.icobin0 -> 174 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-6x6-4bpp.pngbin0 -> 163 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-7x7-4bpp.icobin0 -> 182 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-7x7-4bpp.pngbin0 -> 172 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-8x8-4bpp.icobin0 -> 190 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-8x8-4bpp.pngbin0 -> 188 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-9x9-4bpp.icobin0 -> 234 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-size-9x9-4bpp.pngbin0 -> 198 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-transparent-4bpp.icobin0 -> 3262 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/ico-transparent-4bpp.pngbin0 -> 195 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-4bpp/reftest.list23
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-not-square-transparent-8bpp.icobin0 -> 1478 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-not-square-transparent-8bpp.pngbin0 -> 514 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-partial-transparent-8bpp.icobin0 -> 2238 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-partial-transparent-8bpp.pngbin0 -> 983 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-15x15-8bpp.icobin0 -> 1386 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-15x15-8bpp.pngbin0 -> 809 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-16x16-8bpp.icobin0 -> 1406 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-16x16-8bpp.pngbin0 -> 903 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-17x17-8bpp.icobin0 -> 1494 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-17x17-8bpp.pngbin0 -> 964 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-1x1-8bpp.icobin0 -> 1094 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-1x1-8bpp.pngbin0 -> 70 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-256x256-8bpp.icobin0 -> 74814 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-256x256-8bpp.pngbin0 -> 22443 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-2x2-8bpp.icobin0 -> 1102 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-2x2-8bpp.pngbin0 -> 83 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-31x31-8bpp.icobin0 -> 2238 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-31x31-8bpp.pngbin0 -> 1546 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-32x32-8bpp.icobin0 -> 2238 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-32x32-8bpp.pngbin0 -> 1530 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-33x33-8bpp.icobin0 -> 2538 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-33x33-8bpp.pngbin0 -> 1632 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-3x3-8bpp.icobin0 -> 1110 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-3x3-8bpp.pngbin0 -> 107 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-4x4-8bpp.icobin0 -> 1118 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-4x4-8bpp.pngbin0 -> 136 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-5x5-8bpp.icobin0 -> 1146 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-5x5-8bpp.pngbin0 -> 173 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-6x6-8bpp.icobin0 -> 1158 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-6x6-8bpp.pngbin0 -> 218 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-7x7-8bpp.icobin0 -> 1170 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-7x7-8bpp.pngbin0 -> 271 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-8x8-8bpp.icobin0 -> 286 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-8x8-8bpp.pngbin0 -> 313 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-9x9-8bpp.icobin0 -> 1230 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-size-9x9-8bpp.pngbin0 -> 368 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-transparent-8bpp.icobin0 -> 3262 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/ico-transparent-8bpp.pngbin0 -> 195 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-8bpp/reftest.list23
-rw-r--r--image/test/reftest/ico/ico-bmp-corrupted/16x16.pngbin0 -> 879 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-corrupted/invalid-bpp.icobin0 -> 86 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-corrupted/invalid-compression-RLE4.icobin0 -> 86 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-corrupted/invalid-compression-RLE8.icobin0 -> 86 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-corrupted/invalid-compression.icobin0 -> 830 bytes
-rw-r--r--image/test/reftest/ico/ico-bmp-corrupted/reftest.list10
-rw-r--r--image/test/reftest/ico/ico-bmp-corrupted/wrapper.html80
-rw-r--r--image/test/reftest/ico/ico-mixed/mixed-bmp-png.icobin0 -> 17542 bytes
-rw-r--r--image/test/reftest/ico/ico-mixed/mixed-bmp-png.pngbin0 -> 629 bytes
-rw-r--r--image/test/reftest/ico/ico-mixed/mixed-bmp-png32.pngbin0 -> 940 bytes
-rw-r--r--image/test/reftest/ico/ico-mixed/mixed-bmp-png48.pngbin0 -> 1332 bytes
-rw-r--r--image/test/reftest/ico/ico-mixed/reftest.list3
-rw-r--r--image/test/reftest/ico/ico-png/corrupted_x00n0g01.icobin0 -> 71 bytes
-rw-r--r--image/test/reftest/ico/ico-png/corrupted_xxcrn0g04.icobin0 -> 283 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-15x15-png.icobin0 -> 831 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-15x15-png.pngbin0 -> 809 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-16x16-png.icobin0 -> 901 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-16x16-png.pngbin0 -> 879 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-17x17-png.icobin0 -> 1022 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-17x17-png.pngbin0 -> 1000 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-1x1-png.icobin0 -> 92 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-1x1-png.pngbin0 -> 70 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-256x256-png.icobin0 -> 5934 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-256x256-png.pngbin0 -> 5912 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-2x2-png.icobin0 -> 105 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-2x2-png.pngbin0 -> 83 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-31x31-png.icobin0 -> 2958 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-31x31-png.pngbin0 -> 2936 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-32x32-png.icobin0 -> 3128 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-32x32-png.pngbin0 -> 3106 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-33x33-png.icobin0 -> 3325 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-33x33-png.pngbin0 -> 3303 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-3x3-png.icobin0 -> 129 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-3x3-png.pngbin0 -> 107 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-4x4-png.icobin0 -> 158 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-4x4-png.pngbin0 -> 136 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-5x5-png.icobin0 -> 195 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-5x5-png.pngbin0 -> 173 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-6x6-png.icobin0 -> 240 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-6x6-png.pngbin0 -> 218 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-7x7-png.icobin0 -> 293 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-7x7-png.pngbin0 -> 271 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-8x8-png.icobin0 -> 335 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-8x8-png.pngbin0 -> 313 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-9x9-png.icobin0 -> 390 bytes
-rw-r--r--image/test/reftest/ico/ico-png/ico-size-9x9-png.pngbin0 -> 368 bytes
-rw-r--r--image/test/reftest/ico/ico-png/reftest.list29
-rw-r--r--image/test/reftest/ico/ico-png/tmp.icobin0 -> 1150 bytes
-rw-r--r--image/test/reftest/ico/ico-png/transparent-png.icobin0 -> 1150 bytes
-rw-r--r--image/test/reftest/ico/ico-png/transparent-png.pngbin0 -> 699 bytes
-rw-r--r--image/test/reftest/ico/ico-png/wrapper.html28
-rw-r--r--image/test/reftest/ico/ico-png/x00n0g01.pngbin0 -> 49 bytes
-rw-r--r--image/test/reftest/ico/ico-png/xcrn0g04.pngbin0 -> 261 bytes
-rw-r--r--image/test/reftest/ico/reftest.list11
-rw-r--r--image/test/reftest/img2html.html122
-rw-r--r--image/test/reftest/jpeg/blue.html1
-rw-r--r--image/test/reftest/jpeg/blue.jpgbin0 -> 3937 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-cmyk-1.jpgbin0 -> 1498 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-cmyk-1.pngbin0 -> 2523 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-cmyk-2.jpgbin0 -> 5174 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-cmyk-2.pngbin0 -> 21147 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-gray.jpgbin0 -> 396 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-gray.pngbin0 -> 498 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-progressive-1000-ref.html1
-rw-r--r--image/test/reftest/jpeg/jpg-progressive-1000.html1
-rw-r--r--image/test/reftest/jpeg/jpg-progressive-1000.jpgbin0 -> 34409 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-progressive.jpgbin0 -> 979 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-progressive.pngbin0 -> 3106 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-15x15.jpgbin0 -> 465 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-15x15.pngbin0 -> 809 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-16x16.jpgbin0 -> 443 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-16x16.pngbin0 -> 879 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-17x17.jpgbin0 -> 582 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-17x17.pngbin0 -> 1000 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-1x1.jpgbin0 -> 288 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-1x1.pngbin0 -> 70 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-2x2.jpgbin0 -> 353 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-2x2.pngbin0 -> 83 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-31x31.jpgbin0 -> 773 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-31x31.pngbin0 -> 2936 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-32x32.jpgbin0 -> 759 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-32x32.pngbin0 -> 3106 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-33x33.jpgbin0 -> 941 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-33x33.pngbin0 -> 3303 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-3x3.jpgbin0 -> 429 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-3x3.pngbin0 -> 107 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-4x4.jpgbin0 -> 427 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-4x4.pngbin0 -> 136 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-5x5.jpgbin0 -> 421 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-5x5.pngbin0 -> 173 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-6x6.jpgbin0 -> 218 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-6x6.pngbin0 -> 218 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-7x7.jpgbin0 -> 420 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-7x7.pngbin0 -> 271 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-8x8.jpgbin0 -> 412 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-8x8.pngbin0 -> 313 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-9x9.jpgbin0 -> 438 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-size-9x9.pngbin0 -> 368 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-srgb-icc.jpgbin0 -> 3226 bytes
-rw-r--r--image/test/reftest/jpeg/jpg-srgb-icc.pngbin0 -> 2738 bytes
-rw-r--r--image/test/reftest/jpeg/non-interleaved_progressive-1-halfred-ref.pngbin0 -> 3486 bytes
-rw-r--r--image/test/reftest/jpeg/non-interleaved_progressive-1.jpgbin0 -> 1777 bytes
-rw-r--r--image/test/reftest/jpeg/non-interleaved_progressive-2-white-ref.pngbin0 -> 2303 bytes
-rw-r--r--image/test/reftest/jpeg/non-interleaved_progressive-2.jpgbin0 -> 3000 bytes
-rw-r--r--image/test/reftest/jpeg/red-bad-marker.jpgbin0 -> 640 bytes
-rw-r--r--image/test/reftest/jpeg/red.jpgbin0 -> 3938 bytes
-rw-r--r--image/test/reftest/jpeg/reftest.list73
-rw-r--r--image/test/reftest/jpeg/webcam-simulacrum.html1
-rw-r--r--image/test/reftest/jpeg/webcam-simulacrum.mjpgbin0 -> 7978 bytes
-rw-r--r--image/test/reftest/jpeg/webcam-simulacrum.mjpg^headers^3
-rw-r--r--image/test/reftest/jxl/jxl-size-33x33.jxlbin0 -> 916 bytes
-rw-r--r--image/test/reftest/jxl/jxl-size-33x33.pngbin0 -> 3303 bytes
-rw-r--r--image/test/reftest/jxl/reftest.list3
-rw-r--r--image/test/reftest/pngsuite-ancillary/ccwn2c08.html1242
-rw-r--r--image/test/reftest/pngsuite-ancillary/ccwn2c08.pngbin0 -> 1514 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/ccwn3p08.html1272
-rw-r--r--image/test/reftest/pngsuite-ancillary/ccwn3p08.pngbin0 -> 1554 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/cdfn2c08.html326
-rw-r--r--image/test/reftest/pngsuite-ancillary/cdfn2c08.pngbin0 -> 404 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/cdhn2c08.html278
-rw-r--r--image/test/reftest/pngsuite-ancillary/cdhn2c08.pngbin0 -> 344 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/cdsn2c08.html86
-rw-r--r--image/test/reftest/pngsuite-ancillary/cdsn2c08.pngbin0 -> 232 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/cdun2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/cdun2c08.pngbin0 -> 724 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/ch1n3p04.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/ch1n3p04.pngbin0 -> 258 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/ch2n3p08.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/ch2n3p08.pngbin0 -> 1810 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/cm0n0g04.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/cm0n0g04.pngbin0 -> 292 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/cm7n0g04.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/cm7n0g04.pngbin0 -> 292 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/cm9n0g04.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/cm9n0g04.pngbin0 -> 292 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/cs3n2c16.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/cs3n2c16.pngbin0 -> 214 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/cs3n3p08.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/cs3n3p08.pngbin0 -> 259 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/cs5n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/cs5n2c08.pngbin0 -> 186 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/cs5n3p08.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/cs5n3p08.pngbin0 -> 271 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/cs8n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/cs8n2c08.pngbin0 -> 149 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/cs8n3p08.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/cs8n3p08.pngbin0 -> 256 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/ct0n0g04.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/ct0n0g04.pngbin0 -> 273 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/ct1n0g04.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/ct1n0g04.pngbin0 -> 792 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/ctzn0g04.html1094
-rw-r--r--image/test/reftest/pngsuite-ancillary/ctzn0g04.pngbin0 -> 753 bytes
-rw-r--r--image/test/reftest/pngsuite-ancillary/qcms-asm-check.js28
-rw-r--r--image/test/reftest/pngsuite-ancillary/reftest.list62
-rw-r--r--image/test/reftest/pngsuite-background/bg__4a08.html1092
-rw-r--r--image/test/reftest/pngsuite-background/bg__4a16.html1092
-rw-r--r--image/test/reftest/pngsuite-background/bg__6a08.html1092
-rw-r--r--image/test/reftest/pngsuite-background/bg__6a16.html1092
-rw-r--r--image/test/reftest/pngsuite-background/bgai4a08.pngbin0 -> 214 bytes
-rw-r--r--image/test/reftest/pngsuite-background/bgai4a16.pngbin0 -> 2855 bytes
-rw-r--r--image/test/reftest/pngsuite-background/bgan6a08.pngbin0 -> 184 bytes
-rw-r--r--image/test/reftest/pngsuite-background/bgan6a16.pngbin0 -> 3435 bytes
-rw-r--r--image/test/reftest/pngsuite-background/bgbn4a08.pngbin0 -> 140 bytes
-rw-r--r--image/test/reftest/pngsuite-background/bggn4a16.pngbin0 -> 2220 bytes
-rw-r--r--image/test/reftest/pngsuite-background/bgwn6a08.pngbin0 -> 202 bytes
-rw-r--r--image/test/reftest/pngsuite-background/bgyn6a16.pngbin0 -> 3453 bytes
-rw-r--r--image/test/reftest/pngsuite-background/reftest.list22
-rw-r--r--image/test/reftest/pngsuite-background/wrapper.html28
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi0g01.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi0g01.pngbin0 -> 217 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi0g02.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi0g02.pngbin0 -> 154 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi0g04.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi0g04.pngbin0 -> 247 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi0g08.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi0g08.pngbin0 -> 254 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi0g16.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi0g16.pngbin0 -> 299 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi2c08.pngbin0 -> 315 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi2c16.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi2c16.pngbin0 -> 595 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi3p01.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi3p01.pngbin0 -> 132 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi3p02.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi3p02.pngbin0 -> 193 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi3p04.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi3p04.pngbin0 -> 327 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi3p08.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi3p08.pngbin0 -> 1527 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi4a08.pngbin0 -> 214 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi4a16.pngbin0 -> 2855 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi6a08.pngbin0 -> 361 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/basi6a16.pngbin0 -> 4180 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-i/reftest.list33
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn0g01.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn0g01.pngbin0 -> 164 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn0g02.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn0g02.pngbin0 -> 104 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn0g04.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn0g04.pngbin0 -> 145 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn0g08.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn0g08.pngbin0 -> 138 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn0g16.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn0g16.pngbin0 -> 167 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn2c08.pngbin0 -> 145 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn2c16.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn2c16.pngbin0 -> 302 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn3p01.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn3p01.pngbin0 -> 112 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn3p02.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn3p02.pngbin0 -> 146 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn3p04.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn3p04.pngbin0 -> 216 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn3p08.html1094
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn3p08.pngbin0 -> 1286 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn4a08.pngbin0 -> 126 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn4a16.pngbin0 -> 2206 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn6a08.pngbin0 -> 184 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/basn6a16.pngbin0 -> 3435 bytes
-rw-r--r--image/test/reftest/pngsuite-basic-n/reftest.list33
-rw-r--r--image/test/reftest/pngsuite-chunkorder/color.html1094
-rw-r--r--image/test/reftest/pngsuite-chunkorder/grayscale.html1094
-rw-r--r--image/test/reftest/pngsuite-chunkorder/oi1n0g16.pngbin0 -> 167 bytes
-rw-r--r--image/test/reftest/pngsuite-chunkorder/oi1n2c16.pngbin0 -> 302 bytes
-rw-r--r--image/test/reftest/pngsuite-chunkorder/oi2n0g16.pngbin0 -> 179 bytes
-rw-r--r--image/test/reftest/pngsuite-chunkorder/oi2n2c16.pngbin0 -> 314 bytes
-rw-r--r--image/test/reftest/pngsuite-chunkorder/oi4n0g16.pngbin0 -> 203 bytes
-rw-r--r--image/test/reftest/pngsuite-chunkorder/oi4n2c16.pngbin0 -> 338 bytes
-rw-r--r--image/test/reftest/pngsuite-chunkorder/oi9n0g16.pngbin0 -> 1283 bytes
-rw-r--r--image/test/reftest/pngsuite-chunkorder/oi9n2c16.pngbin0 -> 3038 bytes
-rw-r--r--image/test/reftest/pngsuite-chunkorder/reftest.list21
-rw-r--r--image/test/reftest/pngsuite-corrupted/reftest.list10
-rw-r--r--image/test/reftest/pngsuite-corrupted/wrapper.html28
-rw-r--r--image/test/reftest/pngsuite-corrupted/x00n0g01.pngbin0 -> 49 bytes
-rw-r--r--image/test/reftest/pngsuite-corrupted/xcrn0g04.pngbin0 -> 261 bytes
-rw-r--r--image/test/reftest/pngsuite-corrupted/xlfn0g04.png13
-rw-r--r--image/test/reftest/pngsuite-filtering/f00n0g08.html1094
-rw-r--r--image/test/reftest/pngsuite-filtering/f00n0g08.pngbin0 -> 319 bytes
-rw-r--r--image/test/reftest/pngsuite-filtering/f00n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-filtering/f00n2c08.pngbin0 -> 2475 bytes
-rw-r--r--image/test/reftest/pngsuite-filtering/f01n0g08.html1094
-rw-r--r--image/test/reftest/pngsuite-filtering/f01n0g08.pngbin0 -> 321 bytes
-rw-r--r--image/test/reftest/pngsuite-filtering/f01n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-filtering/f01n2c08.pngbin0 -> 1180 bytes
-rw-r--r--image/test/reftest/pngsuite-filtering/f02n0g08.html1094
-rw-r--r--image/test/reftest/pngsuite-filtering/f02n0g08.pngbin0 -> 355 bytes
-rw-r--r--image/test/reftest/pngsuite-filtering/f02n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-filtering/f02n2c08.pngbin0 -> 1729 bytes
-rw-r--r--image/test/reftest/pngsuite-filtering/f03n0g08.html1094
-rw-r--r--image/test/reftest/pngsuite-filtering/f03n0g08.pngbin0 -> 389 bytes
-rw-r--r--image/test/reftest/pngsuite-filtering/f03n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-filtering/f03n2c08.pngbin0 -> 1291 bytes
-rw-r--r--image/test/reftest/pngsuite-filtering/f04n0g08.html1094
-rw-r--r--image/test/reftest/pngsuite-filtering/f04n0g08.pngbin0 -> 269 bytes
-rw-r--r--image/test/reftest/pngsuite-filtering/f04n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-filtering/f04n2c08.pngbin0 -> 985 bytes
-rw-r--r--image/test/reftest/pngsuite-filtering/reftest.list22
-rw-r--r--image/test/reftest/pngsuite-gamma/g03n0g16.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g03n0g16.pngbin0 -> 345 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g03n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g03n2c08.pngbin0 -> 370 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g03n3p04.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g03n3p04.pngbin0 -> 214 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g04n0g16.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g04n0g16.pngbin0 -> 363 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g04n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g04n2c08.pngbin0 -> 377 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g04n3p04.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g04n3p04.pngbin0 -> 219 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g05n0g16.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g05n0g16.pngbin0 -> 339 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g05n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g05n2c08.pngbin0 -> 350 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g05n3p04.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g05n3p04.pngbin0 -> 206 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g07n0g16.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g07n0g16.pngbin0 -> 321 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g07n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g07n2c08.pngbin0 -> 340 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g07n3p04.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g07n3p04.pngbin0 -> 207 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g10n0g16.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g10n0g16.pngbin0 -> 262 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g10n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g10n2c08.pngbin0 -> 285 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g10n3p04.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g10n3p04.pngbin0 -> 214 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g25n0g16.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g25n0g16.pngbin0 -> 383 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g25n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g25n2c08.pngbin0 -> 405 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/g25n3p04.html1094
-rw-r--r--image/test/reftest/pngsuite-gamma/g25n3p04.pngbin0 -> 215 bytes
-rw-r--r--image/test/reftest/pngsuite-gamma/reftest.list38
-rw-r--r--image/test/reftest/pngsuite-oddsizes/reftest.list77
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s01_3p01.html9
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s01i3p01.pngbin0 -> 113 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s01n3p01.pngbin0 -> 113 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s02_3p01.html14
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s02i3p01.pngbin0 -> 114 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s02n3p01.pngbin0 -> 115 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s03_3p01.html21
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s03i3p01.pngbin0 -> 118 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s03n3p01.pngbin0 -> 120 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s04_3p01.html30
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s04i3p01.pngbin0 -> 126 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s04n3p01.pngbin0 -> 121 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s05_3p02.html41
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s05i3p02.pngbin0 -> 134 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s05n3p02.pngbin0 -> 129 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s06_3p02.html54
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s06i3p02.pngbin0 -> 143 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s06n3p02.pngbin0 -> 131 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s07_3p02.html69
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s07i3p02.pngbin0 -> 149 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s07n3p02.pngbin0 -> 138 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s08_3p02.html86
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s08i3p02.pngbin0 -> 149 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s08n3p02.pngbin0 -> 139 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s09_3p02.html105
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s09i3p02.pngbin0 -> 147 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s09n3p02.pngbin0 -> 143 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s32_3p04.html1094
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s32i3p04.pngbin0 -> 355 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s32n3p04.pngbin0 -> 263 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s33_3p04.html1161
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s33i3p04.pngbin0 -> 385 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s33n3p04.pngbin0 -> 329 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s34_3p04.html1230
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s34i3p04.pngbin0 -> 349 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s34n3p04.pngbin0 -> 248 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s35_3p04.html1301
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s35i3p04.pngbin0 -> 399 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s35n3p04.pngbin0 -> 338 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s36_3p04.html1374
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s36i3p04.pngbin0 -> 356 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s36n3p04.pngbin0 -> 258 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s37_3p04.html1449
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s37i3p04.pngbin0 -> 393 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s37n3p04.pngbin0 -> 336 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s38_3p04.html1526
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s38i3p04.pngbin0 -> 357 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s38n3p04.pngbin0 -> 245 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s39_3p04.html1605
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s39i3p04.pngbin0 -> 420 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s39n3p04.pngbin0 -> 352 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s40_3p04.html1686
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s40i3p04.pngbin0 -> 357 bytes
-rw-r--r--image/test/reftest/pngsuite-oddsizes/s40n3p04.pngbin0 -> 256 bytes
-rw-r--r--image/test/reftest/pngsuite-palettes/pp0n2c16.html1094
-rw-r--r--image/test/reftest/pngsuite-palettes/pp0n2c16.pngbin0 -> 962 bytes
-rw-r--r--image/test/reftest/pngsuite-palettes/pp0n6a08.pngbin0 -> 818 bytes
-rw-r--r--image/test/reftest/pngsuite-palettes/ps1n0g08.html1094
-rw-r--r--image/test/reftest/pngsuite-palettes/ps1n0g08.pngbin0 -> 1477 bytes
-rw-r--r--image/test/reftest/pngsuite-palettes/ps1n2c16.html1094
-rw-r--r--image/test/reftest/pngsuite-palettes/ps1n2c16.pngbin0 -> 1641 bytes
-rw-r--r--image/test/reftest/pngsuite-palettes/ps2n0g08.html1094
-rw-r--r--image/test/reftest/pngsuite-palettes/ps2n0g08.pngbin0 -> 2341 bytes
-rw-r--r--image/test/reftest/pngsuite-palettes/ps2n2c16.html1094
-rw-r--r--image/test/reftest/pngsuite-palettes/ps2n2c16.pngbin0 -> 2505 bytes
-rw-r--r--image/test/reftest/pngsuite-palettes/reftest.list14
-rw-r--r--image/test/reftest/pngsuite-zlib/reftest.list8
-rw-r--r--image/test/reftest/pngsuite-zlib/z00n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-zlib/z00n2c08.pngbin0 -> 3172 bytes
-rw-r--r--image/test/reftest/pngsuite-zlib/z03n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-zlib/z03n2c08.pngbin0 -> 232 bytes
-rw-r--r--image/test/reftest/pngsuite-zlib/z06n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-zlib/z06n2c08.pngbin0 -> 224 bytes
-rw-r--r--image/test/reftest/pngsuite-zlib/z09n2c08.html1094
-rw-r--r--image/test/reftest/pngsuite-zlib/z09n2c08.pngbin0 -> 224 bytes
-rw-r--r--image/test/reftest/reftest.list55
-rw-r--r--image/test/reftest/webp/blue.pngbin0 -> 100 bytes
-rw-r--r--image/test/reftest/webp/icc-bit-no-icc-chunk.webpbin0 -> 78 bytes
-rw-r--r--image/test/reftest/webp/reftest.list1
-rw-r--r--image/test/unit/async_load_tests.js298
-rw-r--r--image/test/unit/bug413512.icobin0 -> 17759 bytes
-rw-r--r--image/test/unit/bug815359.icobin0 -> 4286 bytes
-rw-r--r--image/test/unit/image1.pngbin0 -> 8415 bytes
-rw-r--r--image/test/unit/image1.webpbin0 -> 3206 bytes
-rw-r--r--image/test/unit/image1png16x16.jpgbin0 -> 1050 bytes
-rw-r--r--image/test/unit/image1png64x64.jpgbin0 -> 4507 bytes
-rw-r--r--image/test/unit/image1quality50.webpbin0 -> 1944 bytes
-rw-r--r--image/test/unit/image2.jpgbin0 -> 3494 bytes
-rw-r--r--image/test/unit/image2jpg16x16-win.pngbin0 -> 948 bytes
-rw-r--r--image/test/unit/image2jpg16x16.pngbin0 -> 955 bytes
-rw-r--r--image/test/unit/image2jpg16x16cropped.jpgbin0 -> 879 bytes
-rw-r--r--image/test/unit/image2jpg16x16cropped2.jpgbin0 -> 878 bytes
-rw-r--r--image/test/unit/image2jpg16x32cropped3.jpgbin0 -> 1127 bytes
-rw-r--r--image/test/unit/image2jpg16x32scaled.jpgbin0 -> 1219 bytes
-rw-r--r--image/test/unit/image2jpg32x16cropped4.jpgbin0 -> 1135 bytes
-rw-r--r--image/test/unit/image2jpg32x16scaled.jpgbin0 -> 1227 bytes
-rw-r--r--image/test/unit/image2jpg32x32-win.pngbin0 -> 3104 bytes
-rw-r--r--image/test/unit/image2jpg32x32.jpgbin0 -> 1634 bytes
-rw-r--r--image/test/unit/image2jpg32x32.pngbin0 -> 3026 bytes
-rw-r--r--image/test/unit/image3.icobin0 -> 1406 bytes
-rw-r--r--image/test/unit/image3ico16x16.pngbin0 -> 520 bytes
-rw-r--r--image/test/unit/image3ico32x32.pngbin0 -> 2280 bytes
-rw-r--r--image/test/unit/image4.gifbin0 -> 1809 bytes
-rw-r--r--image/test/unit/image4gif16x16bmp24bpp.icobin0 -> 894 bytes
-rw-r--r--image/test/unit/image4gif16x16bmp32bpp.icobin0 -> 1150 bytes
-rw-r--r--image/test/unit/image4gif32x32bmp24bpp.icobin0 -> 3262 bytes
-rw-r--r--image/test/unit/image4gif32x32bmp32bpp.icobin0 -> 4286 bytes
-rw-r--r--image/test/unit/image_load_helpers.js124
-rw-r--r--image/test/unit/test_async_notification.js15
-rw-r--r--image/test/unit/test_async_notification_404.js23
-rw-r--r--image/test/unit/test_async_notification_animated.js19
-rw-r--r--image/test/unit/test_encoder_apng.js582
-rw-r--r--image/test/unit/test_encoder_png.js263
-rw-r--r--image/test/unit/test_imgtools.js869
-rw-r--r--image/test/unit/test_moz_icon_uri.js157
-rw-r--r--image/test/unit/test_private_channel.js166
-rw-r--r--image/test/unit/xpcshell.ini42
1653 files changed, 184261 insertions, 0 deletions
diff --git a/image/AnimationFrameBuffer.cpp b/image/AnimationFrameBuffer.cpp
new file mode 100644
index 0000000000..6ef855bbd0
--- /dev/null
+++ b/image/AnimationFrameBuffer.cpp
@@ -0,0 +1,471 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "AnimationFrameBuffer.h"
+
+#include <utility> // for Move
+
+namespace mozilla {
+namespace image {
+
+AnimationFrameRetainedBuffer::AnimationFrameRetainedBuffer(size_t aThreshold,
+ size_t aBatch,
+ size_t aStartFrame)
+ : AnimationFrameBuffer(aBatch, aStartFrame), mThreshold(aThreshold) {
+ // To simplify the code, we have the assumption that the threshold for
+ // entering discard-after-display mode is at least twice the batch size (since
+ // that is the most frames-pending-decode we will request) + 1 for the current
+ // frame. That way the redecoded frames being inserted will never risk
+ // overlapping the frames we will discard due to the animation progressing.
+ // That may cause us to use a little more memory than we want but that is an
+ // acceptable tradeoff for simplicity.
+ size_t minThreshold = 2 * mBatch + 1;
+ if (mThreshold < minThreshold) {
+ mThreshold = minThreshold;
+ }
+
+ // The maximum number of frames we should ever have decoded at one time is
+ // twice the batch. That is a good as number as any to start our decoding at.
+ mPending = mBatch * 2;
+}
+
+bool AnimationFrameRetainedBuffer::InsertInternal(RefPtr<imgFrame>&& aFrame) {
+ // We should only insert new frames if we actually asked for them.
+ MOZ_ASSERT(!mSizeKnown);
+ MOZ_ASSERT(mFrames.Length() < mThreshold);
+
+ ++mSize;
+ mFrames.AppendElement(std::move(aFrame));
+ MOZ_ASSERT(mSize == mFrames.Length());
+ return mSize < mThreshold;
+}
+
+bool AnimationFrameRetainedBuffer::ResetInternal() {
+ // If we haven't crossed the threshold, then we know by definition we have
+ // not discarded any frames. If we previously requested more frames, but
+ // it would have been more than we would have buffered otherwise, we can
+ // stop the decoding after one more frame.
+ if (mPending > 1 && mSize >= mBatch * 2 + 1) {
+ MOZ_ASSERT(!mSizeKnown);
+ mPending = 1;
+ }
+
+ // Either the decoder is still running, or we have enough frames already.
+ // No need for us to restart it.
+ return false;
+}
+
+bool AnimationFrameRetainedBuffer::MarkComplete(
+ const gfx::IntRect& aFirstFrameRefreshArea) {
+ MOZ_ASSERT(!mSizeKnown);
+ mFirstFrameRefreshArea = aFirstFrameRefreshArea;
+ mSizeKnown = true;
+ mPending = 0;
+ mFrames.Compact();
+ return false;
+}
+
+void AnimationFrameRetainedBuffer::AdvanceInternal() {
+ // We should not have advanced if we never inserted.
+ MOZ_ASSERT(!mFrames.IsEmpty());
+ // We only want to change the current frame index if we have advanced. This
+ // means either a higher frame index, or going back to the beginning.
+ size_t framesLength = mFrames.Length();
+ // We should never have advanced beyond the frame buffer.
+ MOZ_ASSERT(mGetIndex < framesLength);
+ // We should never advance if the current frame is null -- it needs to know
+ // the timeout from it at least to know when to advance.
+ MOZ_ASSERT_IF(mGetIndex > 0, mFrames[mGetIndex - 1]);
+ MOZ_ASSERT_IF(mGetIndex == 0, mFrames[framesLength - 1]);
+ // The owner should have already accessed the next frame, so it should also
+ // be available.
+ MOZ_ASSERT(mFrames[mGetIndex]);
+
+ if (!mSizeKnown) {
+ // Calculate how many frames we have requested ahead of the current frame.
+ size_t buffered = mPending + framesLength - mGetIndex - 1;
+ if (buffered < mBatch) {
+ // If we have fewer frames than the batch size, then ask for more. If we
+ // do not have any pending, then we know that there is no active decoding.
+ mPending += mBatch;
+ }
+ }
+}
+
+imgFrame* AnimationFrameRetainedBuffer::Get(size_t aFrame, bool aForDisplay) {
+ // We should not have asked for a frame if we never inserted.
+ if (mFrames.IsEmpty()) {
+ MOZ_ASSERT_UNREACHABLE("Calling Get() when we have no frames");
+ return nullptr;
+ }
+
+ // If we don't have that frame, return an empty frame ref.
+ if (aFrame >= mFrames.Length()) {
+ return nullptr;
+ }
+
+ // If we have space for the frame, it should always be available.
+ if (!mFrames[aFrame]) {
+ MOZ_ASSERT_UNREACHABLE("Calling Get() when frame is unavailable");
+ return nullptr;
+ }
+
+ // If we are advancing on behalf of the animation, we don't expect it to be
+ // getting any frames (besides the first) until we get the desired frame.
+ MOZ_ASSERT(aFrame == 0 || mAdvance == 0);
+ return mFrames[aFrame].get();
+}
+
+bool AnimationFrameRetainedBuffer::IsFirstFrameFinished() const {
+ return !mFrames.IsEmpty() && mFrames[0]->IsFinished();
+}
+
+bool AnimationFrameRetainedBuffer::IsLastInsertedFrame(imgFrame* aFrame) const {
+ return !mFrames.IsEmpty() && mFrames.LastElement().get() == aFrame;
+}
+
+void AnimationFrameRetainedBuffer::AddSizeOfExcludingThis(
+ MallocSizeOf aMallocSizeOf, const AddSizeOfCb& aCallback) {
+ size_t i = 0;
+ for (const RefPtr<imgFrame>& frame : mFrames) {
+ ++i;
+ frame->AddSizeOfExcludingThis(aMallocSizeOf,
+ [&](AddSizeOfCbData& aMetadata) {
+ aMetadata.mIndex = i;
+ aCallback(aMetadata);
+ });
+ }
+}
+
+AnimationFrameDiscardingQueue::AnimationFrameDiscardingQueue(
+ AnimationFrameRetainedBuffer&& aQueue)
+ : AnimationFrameBuffer(aQueue),
+ mInsertIndex(aQueue.mFrames.Length()),
+ mFirstFrame(aQueue.mFrames[0]) {
+ MOZ_ASSERT(!mSizeKnown);
+ MOZ_ASSERT(!mRedecodeError);
+ MOZ_ASSERT(mInsertIndex > 0);
+ mMayDiscard = true;
+
+ // We avoided moving aQueue.mFrames[0] for mFirstFrame above because it is
+ // possible the animation was reset back to the beginning, and then we crossed
+ // the threshold without advancing further. That would mean mGetIndex is 0.
+ for (size_t i = mGetIndex; i < mInsertIndex; ++i) {
+ MOZ_ASSERT(aQueue.mFrames[i]);
+ mDisplay.push_back(std::move(aQueue.mFrames[i]));
+ }
+}
+
+bool AnimationFrameDiscardingQueue::InsertInternal(RefPtr<imgFrame>&& aFrame) {
+ if (mInsertIndex == mSize) {
+ if (mSizeKnown) {
+ // We produced more frames on a subsequent decode than on the first pass.
+ mRedecodeError = true;
+ mPending = 0;
+ return true;
+ }
+ ++mSize;
+ }
+
+ // Even though we don't use redecoded first frames for display purposes, we
+ // will still use them for recycling, so we still need to insert it.
+ mDisplay.push_back(std::move(aFrame));
+ ++mInsertIndex;
+ MOZ_ASSERT(mInsertIndex <= mSize);
+ return true;
+}
+
+bool AnimationFrameDiscardingQueue::ResetInternal() {
+ mDisplay.clear();
+ mInsertIndex = 0;
+
+ bool restartDecoder = mPending == 0;
+ mPending = 2 * mBatch;
+ return restartDecoder;
+}
+
+bool AnimationFrameDiscardingQueue::MarkComplete(
+ const gfx::IntRect& aFirstFrameRefreshArea) {
+ if (NS_WARN_IF(mInsertIndex != mSize)) {
+ mRedecodeError = true;
+ mPending = 0;
+ }
+
+ // If we encounter a redecode error, just make the first frame refresh area to
+ // be the full frame, because we don't really know what we can safely recycle.
+ mFirstFrameRefreshArea =
+ mRedecodeError ? mFirstFrame->GetRect() : aFirstFrameRefreshArea;
+
+ // We reached the end of the animation, the next frame we get, if we get
+ // another, will be the first frame again.
+ mInsertIndex = 0;
+ mSizeKnown = true;
+
+ // Since we only request advancing when we want to resume at a certain point
+ // in the animation, we should never exceed the number of frames.
+ MOZ_ASSERT(mAdvance == 0);
+ return mPending > 0;
+}
+
+void AnimationFrameDiscardingQueue::AdvanceInternal() {
+ // We only want to change the current frame index if we have advanced. This
+ // means either a higher frame index, or going back to the beginning.
+ // We should never have advanced beyond the frame buffer.
+ MOZ_ASSERT(mGetIndex < mSize);
+
+ // We should have the current frame still in the display queue. Either way,
+ // we should at least have an entry in the queue which we need to consume.
+ MOZ_ASSERT(!mDisplay.empty());
+ MOZ_ASSERT(mDisplay.front());
+ mDisplay.pop_front();
+ MOZ_ASSERT(!mDisplay.empty());
+ MOZ_ASSERT(mDisplay.front());
+
+ if (mDisplay.size() + mPending - 1 < mBatch) {
+ // If we have fewer frames than the batch size, then ask for more. If we
+ // do not have any pending, then we know that there is no active decoding.
+ mPending += mBatch;
+ }
+}
+
+imgFrame* AnimationFrameDiscardingQueue::Get(size_t aFrame, bool aForDisplay) {
+ // The first frame is stored separately. If we only need the frame for
+ // display purposes, we can return it right away. If we need it for advancing
+ // the animation, we want to verify the recreated first frame is available
+ // before allowing it continue.
+ if (aForDisplay && aFrame == 0) {
+ return mFirstFrame.get();
+ }
+
+ // If we don't have that frame, return an empty frame ref.
+ if (aFrame >= mSize) {
+ return nullptr;
+ }
+
+ size_t offset;
+ if (aFrame >= mGetIndex) {
+ offset = aFrame - mGetIndex;
+ } else if (!mSizeKnown) {
+ MOZ_ASSERT_UNREACHABLE("Requesting previous frame after we have advanced!");
+ return nullptr;
+ } else {
+ offset = mSize - mGetIndex + aFrame;
+ }
+
+ if (offset >= mDisplay.size()) {
+ return nullptr;
+ }
+
+ // If we are advancing on behalf of the animation, we don't expect it to be
+ // getting any frames (besides the first) until we get the desired frame.
+ MOZ_ASSERT(aFrame == 0 || mAdvance == 0);
+
+ // If we have space for the frame, it should always be available.
+ MOZ_ASSERT(mDisplay[offset]);
+ return mDisplay[offset].get();
+}
+
+bool AnimationFrameDiscardingQueue::IsFirstFrameFinished() const {
+ MOZ_ASSERT(mFirstFrame);
+ MOZ_ASSERT(mFirstFrame->IsFinished());
+ return true;
+}
+
+bool AnimationFrameDiscardingQueue::IsLastInsertedFrame(
+ imgFrame* aFrame) const {
+ return !mDisplay.empty() && mDisplay.back().get() == aFrame;
+}
+
+void AnimationFrameDiscardingQueue::AddSizeOfExcludingThis(
+ MallocSizeOf aMallocSizeOf, const AddSizeOfCb& aCallback) {
+ mFirstFrame->AddSizeOfExcludingThis(aMallocSizeOf,
+ [&](AddSizeOfCbData& aMetadata) {
+ aMetadata.mIndex = 1;
+ aCallback(aMetadata);
+ });
+
+ size_t i = mGetIndex;
+ for (const RefPtr<imgFrame>& frame : mDisplay) {
+ ++i;
+ if (mSize < i) {
+ i = 1;
+ if (mFirstFrame.get() == frame.get()) {
+ // First frame again, we already covered it above. We can have a
+ // different frame in the first frame position in the discard queue
+ // on subsequent passes of the animation. This is useful for recycling.
+ continue;
+ }
+ }
+
+ frame->AddSizeOfExcludingThis(aMallocSizeOf,
+ [&](AddSizeOfCbData& aMetadata) {
+ aMetadata.mIndex = i;
+ aCallback(aMetadata);
+ });
+ }
+}
+
+AnimationFrameRecyclingQueue::AnimationFrameRecyclingQueue(
+ AnimationFrameRetainedBuffer&& aQueue)
+ : AnimationFrameDiscardingQueue(std::move(aQueue)),
+ mForceUseFirstFrameRefreshArea(false) {
+ // In an ideal world, we would always save the already displayed frames for
+ // recycling but none of the frames were marked as recyclable. We will incur
+ // the extra allocation cost for a few more frames.
+ mRecycling = true;
+
+ // Until we reach the end of the animation, set the first frame refresh area
+ // to match that of the full area of the first frame.
+ mFirstFrameRefreshArea = mFirstFrame->GetRect();
+}
+
+void AnimationFrameRecyclingQueue::AddSizeOfExcludingThis(
+ MallocSizeOf aMallocSizeOf, const AddSizeOfCb& aCallback) {
+ AnimationFrameDiscardingQueue::AddSizeOfExcludingThis(aMallocSizeOf,
+ aCallback);
+
+ for (const RecycleEntry& entry : mRecycle) {
+ if (entry.mFrame) {
+ entry.mFrame->AddSizeOfExcludingThis(
+ aMallocSizeOf, [&](AddSizeOfCbData& aMetadata) {
+ aMetadata.mIndex = 0; // Frame is not applicable
+ aCallback(aMetadata);
+ });
+ }
+ }
+}
+
+void AnimationFrameRecyclingQueue::AdvanceInternal() {
+ // We only want to change the current frame index if we have advanced. This
+ // means either a higher frame index, or going back to the beginning.
+ // We should never have advanced beyond the frame buffer.
+ MOZ_ASSERT(mGetIndex < mSize);
+
+ MOZ_ASSERT(!mDisplay.empty());
+ MOZ_ASSERT(mDisplay.front());
+
+ // We have advanced past the first frame. That means the next frame we are
+ // putting in the queue to recycling is the first frame in the animation,
+ // and we no longer need to worry about having looped around.
+ if (mGetIndex == 1) {
+ mForceUseFirstFrameRefreshArea = false;
+ }
+
+ RefPtr<imgFrame>& front = mDisplay.front();
+ RecycleEntry newEntry(mForceUseFirstFrameRefreshArea ? mFirstFrameRefreshArea
+ : front->GetDirtyRect());
+
+ // If we are allowed to recycle the frame, then we should save it before the
+ // base class's AdvanceInternal discards it.
+ newEntry.mFrame = std::move(front);
+
+ // Even if the frame itself isn't saved, we want the dirty rect to calculate
+ // the recycle rect for future recycled frames.
+ mRecycle.push_back(std::move(newEntry));
+ mDisplay.pop_front();
+ MOZ_ASSERT(!mDisplay.empty());
+ MOZ_ASSERT(mDisplay.front());
+
+ if (mDisplay.size() + mPending - 1 < mBatch) {
+ // If we have fewer frames than the batch size, then ask for more. If we
+ // do not have any pending, then we know that there is no active decoding.
+ //
+ // We limit the batch to avoid using the frame we just added to the queue.
+ // This gives other parts of the system time to switch to the new current
+ // frame, and maximize buffer reuse. In particular this is useful for
+ // WebRender which holds onto the previous frame for much longer.
+ size_t newPending = std::min(mPending + mBatch, mRecycle.size() - 1);
+ if (newPending == 0 && (mDisplay.size() <= 1 || mPending > 0)) {
+ // If we already have pending frames, then the decoder is active and we
+ // cannot go below one. If we are displaying the only frame we have, and
+ // there are none pending, then we must request at least one more frame to
+ // continue to animation, because we won't advance again without a new
+ // frame. This may cause us to skip recycling because the previous frame
+ // is still in use.
+ newPending = 1;
+ }
+ mPending = newPending;
+ }
+}
+
+bool AnimationFrameRecyclingQueue::ResetInternal() {
+ // We should save any display frames that we can to save on at least the
+ // allocation. The first frame refresh area is guaranteed to be the aggregate
+ // dirty rect or the entire frame, and so the bare minimum area we can
+ // recycle. We don't need to worry about updating the dirty rect for the
+ // existing mRecycle entries, because that will happen in RecycleFrame when
+ // we try to pull out a frame to redecode the first frame.
+ for (RefPtr<imgFrame>& frame : mDisplay) {
+ RecycleEntry newEntry(mFirstFrameRefreshArea);
+ newEntry.mFrame = std::move(frame);
+ mRecycle.push_back(std::move(newEntry));
+ }
+
+ return AnimationFrameDiscardingQueue::ResetInternal();
+}
+
+RawAccessFrameRef AnimationFrameRecyclingQueue::RecycleFrame(
+ gfx::IntRect& aRecycleRect) {
+ if (mInsertIndex == 0) {
+ // If we are recreating the first frame, then we actually have already
+ // precomputed aggregate of the dirty rects as the first frame refresh
+ // area. We know that all of the frames still in the recycling queue
+ // need to take into account the same dirty rect because they are also
+ // frames which cross the boundary.
+ //
+ // Note that this may actually shrink the dirty rect if we estimated it
+ // earlier with the full frame size and now we have the actual, more
+ // conservative aggregate for the animation.
+ for (RecycleEntry& entry : mRecycle) {
+ entry.mDirtyRect = mFirstFrameRefreshArea;
+ }
+ // Until we advance to the first frame again, any subsequent recycled
+ // frames should also use the first frame refresh area.
+ mForceUseFirstFrameRefreshArea = true;
+ }
+
+ if (mRecycle.empty()) {
+ return RawAccessFrameRef();
+ }
+
+ RawAccessFrameRef recycledFrame;
+ if (mRecycle.front().mFrame) {
+ recycledFrame = mRecycle.front().mFrame->RawAccessRef();
+ MOZ_ASSERT(recycledFrame);
+ mRecycle.pop_front();
+
+ if (mForceUseFirstFrameRefreshArea) {
+ // We are still crossing the loop boundary and cannot rely upon the dirty
+ // rects of entries in mDisplay to be representative. E.g. The first frame
+ // is probably has a full frame dirty rect.
+ aRecycleRect = mFirstFrameRefreshArea;
+ } else {
+ // Calculate the recycle rect for the recycled frame. This is the
+ // cumulative dirty rect of all of the frames ahead of us to be displayed,
+ // and to be used for recycling. Or in other words, the dirty rect between
+ // the recycled frame and the decoded frame which reuses the buffer.
+ //
+ // We know at this point that mRecycle contains either frames from the end
+ // of the animation with the first frame refresh area as the dirty rect
+ // (plus the first frame likewise) and frames with their actual dirty rect
+ // from the start. mDisplay should also only contain frames from the start
+ // of the animation onwards.
+ aRecycleRect.SetRect(0, 0, 0, 0);
+ for (const RefPtr<imgFrame>& frame : mDisplay) {
+ aRecycleRect = aRecycleRect.Union(frame->GetDirtyRect());
+ }
+ for (const RecycleEntry& entry : mRecycle) {
+ aRecycleRect = aRecycleRect.Union(entry.mDirtyRect);
+ }
+ }
+ } else {
+ mRecycle.pop_front();
+ }
+
+ return recycledFrame;
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/AnimationFrameBuffer.h b/image/AnimationFrameBuffer.h
new file mode 100644
index 0000000000..b812fe4630
--- /dev/null
+++ b/image/AnimationFrameBuffer.h
@@ -0,0 +1,480 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_AnimationFrameBuffer_h
+#define mozilla_image_AnimationFrameBuffer_h
+
+#include "ISurfaceProvider.h"
+#include <deque>
+
+namespace mozilla {
+namespace image {
+
+/**
+ * An AnimationFrameBuffer owns the frames outputted by an animated image
+ * decoder as well as directing its owner on how to drive the decoder,
+ * whether to produce more or to stop.
+ *
+ * This should be subclassed by the different types of queues, depending on
+ * what behaviour is desired.
+ */
+class AnimationFrameBuffer {
+ public:
+ enum class InsertStatus : uint8_t {
+ YIELD, // No more frames required at this time.
+ CONTINUE, // Continue decoding more frames.
+ DISCARD_YIELD, // Crossed threshold, switch to discarding structure
+ // and stop decoding more frames.
+ DISCARD_CONTINUE // Crossed threshold, switch to discarding structure
+ // and continue decoding more frames.
+ };
+
+ /**
+ * @param aBatch Number of frames we request to be decoded each time it
+ * decides we need more.
+ *
+ * @param aStartFrame The starting frame for the animation. The frame buffer
+ * will auto-advance (and thus keep the decoding pipeline
+ * going) until it has reached this frame. Useful when the
+ * animation was progressing, but the surface was
+ * discarded, and we had to redecode.
+ */
+ AnimationFrameBuffer(size_t aBatch, size_t aStartFrame)
+ : mSize(0),
+ mBatch(aBatch),
+ mGetIndex(0),
+ mAdvance(aStartFrame),
+ mPending(0),
+ mSizeKnown(false),
+ mMayDiscard(false),
+ mRedecodeError(false),
+ mRecycling(false) {
+ if (mBatch > SIZE_MAX / 4) {
+ // Batch size is so big, we will just end up decoding the whole animation.
+ mBatch = SIZE_MAX / 4;
+ } else if (mBatch < 1) {
+ // Never permit a batch size smaller than 1. We always want to be asking
+ // for at least one frame to start.
+ mBatch = 1;
+ }
+ }
+
+ AnimationFrameBuffer(const AnimationFrameBuffer& aOther)
+ : mSize(aOther.mSize),
+ mBatch(aOther.mBatch),
+ mGetIndex(aOther.mGetIndex),
+ mAdvance(aOther.mAdvance),
+ mPending(aOther.mPending),
+ mSizeKnown(aOther.mSizeKnown),
+ mMayDiscard(aOther.mMayDiscard),
+ mRedecodeError(aOther.mRedecodeError),
+ mRecycling(aOther.mRecycling) {}
+
+ virtual ~AnimationFrameBuffer() {}
+
+ /**
+ * @returns True if frames post-advance may be discarded and redecoded on
+ * demand, else false.
+ */
+ bool MayDiscard() const { return mMayDiscard; }
+
+ /**
+ * @returns True if frames post-advance may be reused after displaying, else
+ * false. Implies MayDiscard().
+ */
+ bool IsRecycling() const {
+ MOZ_ASSERT_IF(mRecycling, mMayDiscard);
+ return mRecycling;
+ }
+
+ /**
+ * @returns True if the frame buffer was ever marked as complete. This implies
+ * that the total number of frames is known and may be gotten from
+ * Frames().Length().
+ */
+ bool SizeKnown() const { return mSizeKnown; }
+
+ /**
+ * @returns The total number of frames in the animation. If SizeKnown() is
+ * true, then this is a constant, else it is just the total number of
+ * frames we have decoded thus far.
+ */
+ size_t Size() const { return mSize; }
+
+ /**
+ * @returns The first frame refresh area. This is used instead of the dirty
+ * rect for the last frame when transitioning back to the first frame.
+ */
+ const gfx::IntRect& FirstFrameRefreshArea() const {
+ return mFirstFrameRefreshArea;
+ }
+
+ /**
+ * @returns True if encountered an error during redecode which should cause
+ * the caller to stop inserting frames.
+ */
+ bool HasRedecodeError() const { return mRedecodeError; }
+
+ /**
+ * @returns The current frame index we have advanced to.
+ */
+ size_t Displayed() const { return mGetIndex; }
+
+ /**
+ * @returns Outstanding frames desired from the decoder.
+ */
+ size_t PendingDecode() const { return mPending; }
+
+ /**
+ * @returns Outstanding frames to advance internally.
+ */
+ size_t PendingAdvance() const { return mAdvance; }
+
+ /**
+ * @returns Number of frames we request to be decoded each time it decides we
+ * need more.
+ */
+ size_t Batch() const { return mBatch; }
+
+ /**
+ * Resets the currently displayed frame of the frame buffer to the beginning.
+ *
+ * @returns True if the caller should restart the decoder.
+ */
+ bool Reset() {
+ mGetIndex = 0;
+ mAdvance = 0;
+ return ResetInternal();
+ }
+
+ /**
+ * Advance the currently displayed frame of the frame buffer. If it reaches
+ * the end, it will loop back to the beginning. It should not be called unless
+ * a call to Get has returned a valid frame for the next frame index.
+ *
+ * As we advance, the number of frames we have buffered ahead of the current
+ * will shrink. Once that becomes too few, we will request a batch-sized set
+ * of frames to be decoded from the decoder.
+ *
+ * @param aExpectedFrame The frame we expect to have advanced to. This is
+ * used for confirmation purposes (e.g. asserts).
+ *
+ * @returns True if the caller should restart the decoder.
+ */
+ bool AdvanceTo(size_t aExpectedFrame) {
+ MOZ_ASSERT(mAdvance == 0);
+
+ if (++mGetIndex == mSize && mSizeKnown) {
+ mGetIndex = 0;
+ }
+ MOZ_ASSERT(mGetIndex == aExpectedFrame);
+
+ bool hasPending = mPending > 0;
+ AdvanceInternal();
+ // Restart the decoder if we transitioned from no pending frames being
+ // decoded, to some pending frames to be decoded.
+ return !hasPending && mPending > 0;
+ }
+
+ /**
+ * Inserts a frame into the frame buffer.
+ *
+ * Once we have a sufficient number of frames buffered relative to the
+ * currently displayed frame, it will return YIELD to indicate the caller
+ * should stop decoding. Otherwise it will return CONTINUE.
+ *
+ * If we cross the threshold, it will return DISCARD_YIELD or DISCARD_CONTINUE
+ * to indicate that the caller should switch to a new queue type.
+ *
+ * @param aFrame The frame to insert into the buffer.
+ *
+ * @returns True if the decoder should decode another frame.
+ */
+ InsertStatus Insert(RefPtr<imgFrame>&& aFrame) {
+ MOZ_ASSERT(mPending > 0);
+ MOZ_ASSERT(aFrame);
+
+ --mPending;
+ bool retain = InsertInternal(std::move(aFrame));
+
+ if (mAdvance > 0 && mSize > 1) {
+ --mAdvance;
+ ++mGetIndex;
+ AdvanceInternal();
+ }
+
+ if (!retain) {
+ return mPending > 0 ? InsertStatus::DISCARD_CONTINUE
+ : InsertStatus::DISCARD_YIELD;
+ }
+
+ return mPending > 0 ? InsertStatus::CONTINUE : InsertStatus::YIELD;
+ }
+
+ /**
+ * Access a specific frame from the frame buffer. It should generally access
+ * frames in sequential order, increasing in tandem with AdvanceTo calls. The
+ * first frame may be accessed at any time. The access order should start with
+ * the same value as that given in Initialize (aStartFrame).
+ *
+ * @param aFrame The frame index to access.
+ *
+ * @returns The frame, if available.
+ */
+ virtual imgFrame* Get(size_t aFrame, bool aForDisplay) = 0;
+
+ /**
+ * @returns True if the first frame of the animation (not of the queue) is
+ * available/finished, else false.
+ */
+ virtual bool IsFirstFrameFinished() const = 0;
+
+ /**
+ * @returns True if the last inserted frame matches the given frame, else
+ * false.
+ */
+ virtual bool IsLastInsertedFrame(imgFrame* aFrame) const = 0;
+
+ /**
+ * This should be called after the last frame has been inserted. If the buffer
+ * is discarding old frames, it may request more frames to be decoded. In this
+ * case that means the decoder should start again from the beginning. This
+ * return value should be used in preference to that of the Insert call.
+ *
+ * @returns True if the decoder should decode another frame.
+ */
+ virtual bool MarkComplete(const gfx::IntRect& aFirstFrameRefreshArea) = 0;
+
+ typedef ISurfaceProvider::AddSizeOfCbData AddSizeOfCbData;
+ typedef ISurfaceProvider::AddSizeOfCb AddSizeOfCb;
+
+ /**
+ * Accumulate the total cost of all the frames in the buffer.
+ */
+ virtual void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
+ const AddSizeOfCb& aCallback) = 0;
+
+ /**
+ * Request a recycled frame buffer, and if available, set aRecycleRect to be
+ * the dirty rect between the contents of the recycled frame, and the restore
+ * frame (e.g. what we composite on top of) for the next frame to be created.
+ *
+ * @returns The frame to be recycled, if available.
+ */
+ virtual RawAccessFrameRef RecycleFrame(gfx::IntRect& aRecycleRect) {
+ MOZ_ASSERT(!mRecycling);
+ return RawAccessFrameRef();
+ }
+
+ protected:
+ /**
+ * Perform the actual insertion of the given frame into the underlying buffer
+ * representation. mGetIndex shall be the index of the frame we are inserting,
+ * and mSize and mPending have already been adjusted as needed.
+ *
+ * @returns True if the caller should continue as normal, false if the discard
+ * threshold was crossed and we should change queue types.
+ */
+ virtual bool InsertInternal(RefPtr<imgFrame>&& aFrame) = 0;
+
+ /**
+ * Advance from the current frame to the immediately adjacent next frame.
+ * mGetIndex shall be the the index of the new current frame after advancing.
+ * mPending may be adjusted to request more frames.
+ */
+ virtual void AdvanceInternal() = 0;
+
+ /**
+ * Discard any frames as necessary for the reset. mPending may be adjusted to
+ * request more frames.
+ *
+ * @returns True if the caller should resume decoding new frames, else false.
+ */
+ virtual bool ResetInternal() = 0;
+
+ /// The first frame refresh area. This is used instead of the dirty rect for
+ /// the last frame when transitioning back to the first frame.
+ gfx::IntRect mFirstFrameRefreshArea;
+
+ // The total number of frames in the animation. If mSizeKnown is true, it is
+ // the actual total regardless of how many frames are available, otherwise it
+ // is the total number of inserted frames.
+ size_t mSize;
+
+ // The minimum number of frames that we want buffered ahead of the display.
+ size_t mBatch;
+
+ // The sequential index of the frame we have advanced to.
+ size_t mGetIndex;
+
+ // The number of frames we need to auto-advance to synchronize with the
+ // caller.
+ size_t mAdvance;
+
+ // The number of frames to decode before we stop.
+ size_t mPending;
+
+ // True if the total number of frames for the animation is known.
+ bool mSizeKnown;
+
+ // True if this buffer may discard frames.
+ bool mMayDiscard;
+
+ // True if we encountered an error while redecoding.
+ bool mRedecodeError;
+
+ // True if this buffer is recycling frames.
+ bool mRecycling;
+};
+
+/**
+ * An AnimationFrameRetainedBuffer will retain all of the frames inserted into
+ * it. Once it crosses its maximum number of frames, it will recommend
+ * conversion to a discarding queue.
+ */
+class AnimationFrameRetainedBuffer final : public AnimationFrameBuffer {
+ public:
+ /**
+ * @param aThreshold Maximum number of frames that may be stored in the frame
+ * buffer before it may discard already displayed frames.
+ * Once exceeded, it will discard the previous frame to the
+ * current frame whenever Advance is called. It always
+ * retains the first frame.
+ *
+ * @param aBatch See AnimationFrameBuffer::AnimationFrameBuffer.
+ *
+ * @param aStartFrame See AnimationFrameBuffer::AnimationFrameBuffer.
+ */
+ AnimationFrameRetainedBuffer(size_t aThreshold, size_t aBatch,
+ size_t aCurrentFrame);
+
+ /**
+ * @returns Maximum number of frames before we start discarding previous
+ * frames post-advance.
+ */
+ size_t Threshold() const { return mThreshold; }
+
+ /**
+ * @returns The frames of this animation, in order. Each element will always
+ * contain a valid frame.
+ */
+ const nsTArray<RefPtr<imgFrame>>& Frames() const { return mFrames; }
+
+ imgFrame* Get(size_t aFrame, bool aForDisplay) override;
+ bool IsFirstFrameFinished() const override;
+ bool IsLastInsertedFrame(imgFrame* aFrame) const override;
+ bool MarkComplete(const gfx::IntRect& aFirstFrameRefreshArea) override;
+ void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
+ const AddSizeOfCb& aCallback) override;
+
+ private:
+ friend class AnimationFrameDiscardingQueue;
+ friend class AnimationFrameRecyclingQueue;
+
+ bool InsertInternal(RefPtr<imgFrame>&& aFrame) override;
+ void AdvanceInternal() override;
+ bool ResetInternal() override;
+
+ // The frames of this animation, in order.
+ nsTArray<RefPtr<imgFrame>> mFrames;
+
+ // The maximum number of frames we can have before discarding.
+ size_t mThreshold;
+};
+
+/**
+ * An AnimationFrameDiscardingQueue will only retain up to mBatch * 2 frames.
+ * When the animation advances, it will discard the old current frame.
+ */
+class AnimationFrameDiscardingQueue : public AnimationFrameBuffer {
+ public:
+ explicit AnimationFrameDiscardingQueue(AnimationFrameRetainedBuffer&& aQueue);
+
+ imgFrame* Get(size_t aFrame, bool aForDisplay) final;
+ bool IsFirstFrameFinished() const final;
+ bool IsLastInsertedFrame(imgFrame* aFrame) const final;
+ bool MarkComplete(const gfx::IntRect& aFirstFrameRefreshArea) override;
+ void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
+ const AddSizeOfCb& aCallback) override;
+
+ const std::deque<RefPtr<imgFrame>>& Display() const { return mDisplay; }
+ const imgFrame* FirstFrame() const { return mFirstFrame; }
+ size_t PendingInsert() const { return mInsertIndex; }
+
+ protected:
+ bool InsertInternal(RefPtr<imgFrame>&& aFrame) override;
+ void AdvanceInternal() override;
+ bool ResetInternal() override;
+
+ /// The sequential index of the frame we inserting next.
+ size_t mInsertIndex;
+
+ /// Queue storing frames to be displayed by the animator. The first frame in
+ /// the queue is the currently displayed frame.
+ std::deque<RefPtr<imgFrame>> mDisplay;
+
+ /// The first frame which is never discarded, and preferentially reused.
+ RefPtr<imgFrame> mFirstFrame;
+};
+
+/**
+ * An AnimationFrameRecyclingQueue will only retain up to mBatch * 2 frames.
+ * When the animation advances, it will place the old current frame into a
+ * recycling queue to be reused for a future allocation. This only works for
+ * animated images where we decoded full sized frames into their own buffers,
+ * so that the buffers are all identically sized and contain the complete frame
+ * data.
+ */
+class AnimationFrameRecyclingQueue final
+ : public AnimationFrameDiscardingQueue {
+ public:
+ explicit AnimationFrameRecyclingQueue(AnimationFrameRetainedBuffer&& aQueue);
+
+ void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
+ const AddSizeOfCb& aCallback) override;
+
+ RawAccessFrameRef RecycleFrame(gfx::IntRect& aRecycleRect) override;
+
+ struct RecycleEntry {
+ explicit RecycleEntry(const gfx::IntRect& aDirtyRect)
+ : mDirtyRect(aDirtyRect) {}
+
+ RecycleEntry(RecycleEntry&& aOther)
+ : mFrame(std::move(aOther.mFrame)), mDirtyRect(aOther.mDirtyRect) {}
+
+ RecycleEntry& operator=(RecycleEntry&& aOther) {
+ mFrame = std::move(aOther.mFrame);
+ mDirtyRect = aOther.mDirtyRect;
+ return *this;
+ }
+
+ RecycleEntry(const RecycleEntry& aOther) = delete;
+ RecycleEntry& operator=(const RecycleEntry& aOther) = delete;
+
+ RefPtr<imgFrame> mFrame; // The frame containing the buffer to recycle.
+ gfx::IntRect mDirtyRect; // The dirty rect of the frame itself.
+ };
+
+ const std::deque<RecycleEntry>& Recycle() const { return mRecycle; }
+
+ protected:
+ void AdvanceInternal() override;
+ bool ResetInternal() override;
+
+ /// Queue storing frames to be recycled by the decoder to produce its future
+ /// frames. May contain up to mBatch frames, where the last frame in the queue
+ /// is adjacent to the first frame in the mDisplay queue.
+ std::deque<RecycleEntry> mRecycle;
+
+ /// Force recycled frames to use the first frame refresh area as their dirty
+ /// rect. This is used when we are recycling frames from the end of an
+ /// animation to produce frames at the beginning of an animation.
+ bool mForceUseFirstFrameRefreshArea;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_AnimationFrameBuffer_h
diff --git a/image/AnimationParams.h b/image/AnimationParams.h
new file mode 100644
index 0000000000..1e20eea04a
--- /dev/null
+++ b/image/AnimationParams.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_AnimationParams_h
+#define mozilla_image_AnimationParams_h
+
+#include <stdint.h>
+#include "mozilla/gfx/Rect.h"
+#include "FrameTimeout.h"
+
+namespace mozilla {
+namespace image {
+
+enum class BlendMethod : int8_t {
+ // All color components of the frame, including alpha, overwrite the current
+ // contents of the frame's output buffer region.
+ SOURCE,
+
+ // The frame should be composited onto the output buffer based on its alpha,
+ // using a simple OVER operation.
+ OVER
+};
+
+enum class DisposalMethod : int8_t {
+ CLEAR_ALL = -1, // Clear the whole image, revealing what's underneath.
+ NOT_SPECIFIED, // Leave the frame and let the new frame draw on top.
+ KEEP, // Leave the frame and let the new frame draw on top.
+ CLEAR, // Clear the frame's area, revealing what's underneath.
+ RESTORE_PREVIOUS // Restore the previous (composited) frame.
+};
+
+struct AnimationParams {
+ AnimationParams(const gfx::IntRect& aBlendRect, const FrameTimeout& aTimeout,
+ uint32_t aFrameNum, BlendMethod aBlendMethod,
+ DisposalMethod aDisposalMethod)
+ : mBlendRect(aBlendRect),
+ mTimeout(aTimeout),
+ mFrameNum(aFrameNum),
+ mBlendMethod(aBlendMethod),
+ mDisposalMethod(aDisposalMethod) {}
+
+ gfx::IntRect mBlendRect;
+ FrameTimeout mTimeout;
+ uint32_t mFrameNum;
+ BlendMethod mBlendMethod;
+ DisposalMethod mDisposalMethod;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_AnimationParams_h
diff --git a/image/AnimationSurfaceProvider.cpp b/image/AnimationSurfaceProvider.cpp
new file mode 100644
index 0000000000..05208a4d19
--- /dev/null
+++ b/image/AnimationSurfaceProvider.cpp
@@ -0,0 +1,534 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "AnimationSurfaceProvider.h"
+
+#include "mozilla/StaticPrefs_image.h"
+#include "mozilla/gfx/gfxVars.h"
+#include "mozilla/layers/SharedSurfacesChild.h"
+#include "mozilla/layers/SourceSurfaceSharedData.h"
+#include "nsProxyRelease.h"
+
+#include "DecodePool.h"
+#include "Decoder.h"
+
+using namespace mozilla::gfx;
+using namespace mozilla::layers;
+
+namespace mozilla {
+namespace image {
+
+AnimationSurfaceProvider::AnimationSurfaceProvider(
+ NotNull<RasterImage*> aImage, const SurfaceKey& aSurfaceKey,
+ NotNull<Decoder*> aDecoder, size_t aCurrentFrame)
+ : ISurfaceProvider(ImageKey(aImage.get()), aSurfaceKey,
+ AvailabilityState::StartAsPlaceholder()),
+ mImage(aImage.get()),
+ mDecodingMutex("AnimationSurfaceProvider::mDecoder"),
+ mDecoder(aDecoder.get()),
+ mFramesMutex("AnimationSurfaceProvider::mFrames"),
+ mCompositedFrameRequested(false),
+ mSharedAnimation(MakeRefPtr<SharedSurfacesAnimation>()) {
+ MOZ_ASSERT(!mDecoder->IsMetadataDecode(),
+ "Use MetadataDecodingTask for metadata decodes");
+ MOZ_ASSERT(!mDecoder->IsFirstFrameDecode(),
+ "Use DecodedSurfaceProvider for single-frame image decodes");
+
+ // Calculate how many frames we need to decode in this animation before we
+ // enter decode-on-demand mode.
+ IntSize frameSize = aSurfaceKey.Size();
+ size_t threshold =
+ (size_t(StaticPrefs::image_animated_decode_on_demand_threshold_kb()) *
+ 1024) /
+ (sizeof(uint32_t) * frameSize.width * frameSize.height);
+ size_t batch = StaticPrefs::image_animated_decode_on_demand_batch_size();
+
+ mFrames.reset(
+ new AnimationFrameRetainedBuffer(threshold, batch, aCurrentFrame));
+}
+
+AnimationSurfaceProvider::~AnimationSurfaceProvider() {
+ DropImageReference();
+
+ mSharedAnimation->Destroy();
+ if (mDecoder) {
+ mDecoder->SetFrameRecycler(nullptr);
+ }
+}
+
+void AnimationSurfaceProvider::DropImageReference() {
+ if (!mImage) {
+ return; // Nothing to do.
+ }
+
+ // RasterImage objects need to be destroyed on the main thread.
+ SurfaceCache::ReleaseImageOnMainThread(mImage.forget());
+}
+
+void AnimationSurfaceProvider::Reset() {
+ // We want to go back to the beginning.
+ bool mayDiscard;
+ bool restartDecoder = false;
+
+ {
+ MutexAutoLock lock(mFramesMutex);
+
+ // If we have not crossed the threshold, we know we haven't discarded any
+ // frames, and thus we know it is safe move our display index back to the
+ // very beginning. It would be cleaner to let the frame buffer make this
+ // decision inside the AnimationFrameBuffer::Reset method, but if we have
+ // crossed the threshold, we need to hold onto the decoding mutex too. We
+ // should avoid blocking the main thread on the decoder threads.
+ mayDiscard = mFrames->MayDiscard();
+ if (!mayDiscard) {
+ restartDecoder = mFrames->Reset();
+ }
+ }
+
+ if (mayDiscard) {
+ // We are over the threshold and have started discarding old frames. In
+ // that case we need to seize the decoding mutex. Thankfully we know that
+ // we are in the process of decoding at most the batch size frames, so
+ // this should not take too long to acquire.
+ MutexAutoLock lock(mDecodingMutex);
+
+ // We may have hit an error while redecoding. Because FrameAnimator is
+ // tightly coupled to our own state, that means we would need to go through
+ // some heroics to resume animating in those cases. The typical reason for
+ // a redecode to fail is out of memory, and recycling should prevent most of
+ // those errors. When image.animated.generate-full-frames has shipped
+ // enabled on a release or two, we can simply remove the old FrameAnimator
+ // blending code and simplify this quite a bit -- just always pop the next
+ // full frame and timeout off the stack.
+ if (mDecoder) {
+ mDecoder = DecoderFactory::CloneAnimationDecoder(mDecoder);
+ MOZ_ASSERT(mDecoder);
+
+ MutexAutoLock lock2(mFramesMutex);
+ restartDecoder = mFrames->Reset();
+ } else {
+ MOZ_ASSERT(mFrames->HasRedecodeError());
+ }
+ }
+
+ if (restartDecoder) {
+ DecodePool::Singleton()->AsyncRun(this);
+ }
+}
+
+void AnimationSurfaceProvider::Advance(size_t aFrame) {
+ bool restartDecoder;
+
+ RefPtr<SourceSurface> surface;
+ IntRect dirtyRect;
+ {
+ // Typical advancement of a frame.
+ MutexAutoLock lock(mFramesMutex);
+ restartDecoder = mFrames->AdvanceTo(aFrame);
+
+ imgFrame* frame = mFrames->Get(aFrame, /* aForDisplay */ true);
+ MOZ_ASSERT(frame);
+ if (aFrame != 0) {
+ dirtyRect = frame->GetDirtyRect();
+ } else {
+ MOZ_ASSERT(mFrames->SizeKnown());
+ dirtyRect = mFrames->FirstFrameRefreshArea();
+ }
+ surface = frame->GetSourceSurface();
+ MOZ_ASSERT(surface);
+ }
+
+ if (restartDecoder) {
+ DecodePool::Singleton()->AsyncRun(this);
+ }
+
+ mCompositedFrameRequested = false;
+ auto* sharedSurface = static_cast<SourceSurfaceSharedData*>(surface.get());
+ mSharedAnimation->SetCurrentFrame(sharedSurface, dirtyRect);
+}
+
+DrawableFrameRef AnimationSurfaceProvider::DrawableRef(size_t aFrame) {
+ MutexAutoLock lock(mFramesMutex);
+
+ if (Availability().IsPlaceholder()) {
+ MOZ_ASSERT_UNREACHABLE("Calling DrawableRef() on a placeholder");
+ return DrawableFrameRef();
+ }
+
+ imgFrame* frame = mFrames->Get(aFrame, /* aForDisplay */ true);
+ if (!frame) {
+ return DrawableFrameRef();
+ }
+
+ return frame->DrawableRef();
+}
+
+already_AddRefed<imgFrame> AnimationSurfaceProvider::GetFrame(size_t aFrame) {
+ MutexAutoLock lock(mFramesMutex);
+
+ if (Availability().IsPlaceholder()) {
+ MOZ_ASSERT_UNREACHABLE("Calling GetFrame() on a placeholder");
+ return nullptr;
+ }
+
+ RefPtr<imgFrame> frame = mFrames->Get(aFrame, /* aForDisplay */ false);
+ MOZ_ASSERT_IF(frame, frame->IsFinished());
+ return frame.forget();
+}
+
+bool AnimationSurfaceProvider::IsFinished() const {
+ MutexAutoLock lock(mFramesMutex);
+
+ if (Availability().IsPlaceholder()) {
+ MOZ_ASSERT_UNREACHABLE("Calling IsFinished() on a placeholder");
+ return false;
+ }
+
+ return mFrames->IsFirstFrameFinished();
+}
+
+bool AnimationSurfaceProvider::IsFullyDecoded() const {
+ MutexAutoLock lock(mFramesMutex);
+ return mFrames->SizeKnown() && !mFrames->MayDiscard();
+}
+
+size_t AnimationSurfaceProvider::LogicalSizeInBytes() const {
+ // When decoding animated images, we need at most three live surfaces: the
+ // composited surface, the previous composited surface for
+ // DisposalMethod::RESTORE_PREVIOUS, and the surface we're currently decoding
+ // into. The composited surfaces are always BGRA. Although the surface we're
+ // decoding into may be paletted, and may be smaller than the real size of the
+ // image, we assume the worst case here.
+ // XXX(seth): Note that this is actually not accurate yet; we're storing the
+ // full sequence of frames, not just the three live surfaces mentioned above.
+ // Unfortunately there's no way to know in advance how many frames an
+ // animation has, so we really can't do better here. This will become correct
+ // once bug 1289954 is complete.
+ IntSize size = GetSurfaceKey().Size();
+ return 3 * size.width * size.height * sizeof(uint32_t);
+}
+
+void AnimationSurfaceProvider::AddSizeOfExcludingThis(
+ MallocSizeOf aMallocSizeOf, const AddSizeOfCb& aCallback) {
+ // Note that the surface cache lock is already held here, and then we acquire
+ // mFramesMutex. For this method, this ordering is unavoidable, which means
+ // that we must be careful to always use the same ordering elsewhere.
+ MutexAutoLock lock(mFramesMutex);
+ mFrames->AddSizeOfExcludingThis(aMallocSizeOf, aCallback);
+}
+
+void AnimationSurfaceProvider::Run() {
+ MutexAutoLock lock(mDecodingMutex);
+
+ if (!mDecoder) {
+ MOZ_ASSERT_UNREACHABLE("Running after decoding finished?");
+ return;
+ }
+
+ while (true) {
+ // Run the decoder.
+ LexerResult result = mDecoder->Decode(WrapNotNull(this));
+
+ if (result.is<TerminalState>()) {
+ // We may have a new frame now, but it's not guaranteed - a decoding
+ // failure or truncated data may mean that no new frame got produced.
+ // Since we're not sure, rather than call CheckForNewFrameAtYield() here
+ // we call CheckForNewFrameAtTerminalState(), which handles both of these
+ // possibilities.
+ bool continueDecoding = CheckForNewFrameAtTerminalState();
+ FinishDecoding();
+
+ // Even if it is the last frame, we may not have enough frames buffered
+ // ahead of the current. If we are shutting down, we want to ensure we
+ // release the thread as soon as possible. The animation may advance even
+ // during shutdown, which keeps us decoding, and thus blocking the decode
+ // pool during teardown.
+ if (!mDecoder || !continueDecoding ||
+ DecodePool::Singleton()->IsShuttingDown()) {
+ return;
+ }
+
+ // Restart from the very beginning because the decoder was recreated.
+ continue;
+ }
+
+ // If there is output available we want to change the entry in the surface
+ // cache from a placeholder to an actual surface now before NotifyProgress
+ // call below so that when consumers get the frame complete notification
+ // from the NotifyProgress they can actually get a surface from the surface
+ // cache.
+ bool checkForNewFrameAtYieldResult = false;
+ if (result == LexerResult(Yield::OUTPUT_AVAILABLE)) {
+ checkForNewFrameAtYieldResult = CheckForNewFrameAtYield();
+ }
+
+ // Notify for the progress we've made so far.
+ if (mImage && mDecoder->HasProgress()) {
+ NotifyProgress(WrapNotNull(mImage), WrapNotNull(mDecoder));
+ }
+
+ if (result == LexerResult(Yield::NEED_MORE_DATA)) {
+ // We can't make any more progress right now. The decoder itself will
+ // ensure that we get reenqueued when more data is available; just return
+ // for now.
+ return;
+ }
+
+ // There's new output available - a new frame! Grab it. If we don't need any
+ // more for the moment we can break out of the loop. If we are shutting
+ // down, we want to ensure we release the thread as soon as possible. The
+ // animation may advance even during shutdown, which keeps us decoding, and
+ // thus blocking the decode pool during teardown.
+ MOZ_ASSERT(result == LexerResult(Yield::OUTPUT_AVAILABLE));
+ if (!checkForNewFrameAtYieldResult ||
+ DecodePool::Singleton()->IsShuttingDown()) {
+ return;
+ }
+ }
+}
+
+bool AnimationSurfaceProvider::CheckForNewFrameAtYield() {
+ mDecodingMutex.AssertCurrentThreadOwns();
+ MOZ_ASSERT(mDecoder);
+
+ bool justGotFirstFrame = false;
+ bool continueDecoding = false;
+
+ {
+ MutexAutoLock lock(mFramesMutex);
+
+ // Try to get the new frame from the decoder.
+ RefPtr<imgFrame> frame = mDecoder->GetCurrentFrame();
+ MOZ_ASSERT(mDecoder->HasFrameToTake());
+ mDecoder->ClearHasFrameToTake();
+
+ if (!frame) {
+ MOZ_ASSERT_UNREACHABLE("Decoder yielded but didn't produce a frame?");
+ return true;
+ }
+
+ // We should've gotten a different frame than last time.
+ MOZ_ASSERT(!mFrames->IsLastInsertedFrame(frame));
+
+ // Append the new frame to the list.
+ AnimationFrameBuffer::InsertStatus status =
+ mFrames->Insert(std::move(frame));
+
+ // If we hit a redecode error, then we actually want to stop. This happens
+ // when we tried to insert more frames than we originally had (e.g. the
+ // original decoder attempt hit an OOM error sooner than we did). Better to
+ // stop the animation than to get out of sync with FrameAnimator.
+ if (mFrames->HasRedecodeError()) {
+ mDecoder = nullptr;
+ return false;
+ }
+
+ switch (status) {
+ case AnimationFrameBuffer::InsertStatus::DISCARD_CONTINUE:
+ continueDecoding = true;
+ [[fallthrough]];
+ case AnimationFrameBuffer::InsertStatus::DISCARD_YIELD:
+ RequestFrameDiscarding();
+ break;
+ case AnimationFrameBuffer::InsertStatus::CONTINUE:
+ continueDecoding = true;
+ break;
+ case AnimationFrameBuffer::InsertStatus::YIELD:
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unhandled insert status!");
+ break;
+ }
+
+ // We only want to handle the first frame if it is the first pass for the
+ // animation decoder. The owning image will be cleared after that.
+ size_t frameCount = mFrames->Size();
+ if (frameCount == 1 && mImage) {
+ justGotFirstFrame = true;
+ }
+ }
+
+ if (justGotFirstFrame) {
+ AnnounceSurfaceAvailable();
+ }
+
+ return continueDecoding;
+}
+
+bool AnimationSurfaceProvider::CheckForNewFrameAtTerminalState() {
+ mDecodingMutex.AssertCurrentThreadOwns();
+ MOZ_ASSERT(mDecoder);
+
+ bool justGotFirstFrame = false;
+ bool continueDecoding;
+
+ {
+ MutexAutoLock lock(mFramesMutex);
+
+ // The decoder may or may not have a new frame for us at this point. Avoid
+ // reinserting the same frame again.
+ RefPtr<imgFrame> frame = mDecoder->GetCurrentFrame();
+
+ // If the decoder didn't finish a new frame (ie if, after starting the
+ // frame, it got an error and aborted the frame and the rest of the decode)
+ // that means it won't be reporting it to the image or FrameAnimator so we
+ // should ignore it too, that's what HasFrameToTake tracks basically.
+ if (!mDecoder->HasFrameToTake()) {
+ frame = nullptr;
+ } else {
+ MOZ_ASSERT(frame);
+ mDecoder->ClearHasFrameToTake();
+ }
+
+ if (!frame || mFrames->IsLastInsertedFrame(frame)) {
+ return mFrames->MarkComplete(mDecoder->GetFirstFrameRefreshArea());
+ }
+
+ // Append the new frame to the list.
+ AnimationFrameBuffer::InsertStatus status =
+ mFrames->Insert(std::move(frame));
+
+ // If we hit a redecode error, then we actually want to stop. This will be
+ // fully handled in FinishDecoding.
+ if (mFrames->HasRedecodeError()) {
+ return false;
+ }
+
+ switch (status) {
+ case AnimationFrameBuffer::InsertStatus::DISCARD_CONTINUE:
+ case AnimationFrameBuffer::InsertStatus::DISCARD_YIELD:
+ RequestFrameDiscarding();
+ break;
+ case AnimationFrameBuffer::InsertStatus::CONTINUE:
+ case AnimationFrameBuffer::InsertStatus::YIELD:
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unhandled insert status!");
+ break;
+ }
+
+ continueDecoding =
+ mFrames->MarkComplete(mDecoder->GetFirstFrameRefreshArea());
+
+ // We only want to handle the first frame if it is the first pass for the
+ // animation decoder. The owning image will be cleared after that.
+ if (mFrames->Size() == 1 && mImage) {
+ justGotFirstFrame = true;
+ }
+ }
+
+ if (justGotFirstFrame) {
+ AnnounceSurfaceAvailable();
+ }
+
+ return continueDecoding;
+}
+
+void AnimationSurfaceProvider::RequestFrameDiscarding() {
+ mDecodingMutex.AssertCurrentThreadOwns();
+ mFramesMutex.AssertCurrentThreadOwns();
+ MOZ_ASSERT(mDecoder);
+
+ if (mFrames->MayDiscard() || mFrames->IsRecycling()) {
+ MOZ_ASSERT_UNREACHABLE("Already replaced frame queue!");
+ return;
+ }
+
+ auto oldFrameQueue =
+ static_cast<AnimationFrameRetainedBuffer*>(mFrames.get());
+
+ MOZ_ASSERT(!mDecoder->GetFrameRecycler());
+ if (StaticPrefs::image_animated_decode_on_demand_recycle_AtStartup()) {
+ mFrames.reset(new AnimationFrameRecyclingQueue(std::move(*oldFrameQueue)));
+ mDecoder->SetFrameRecycler(this);
+ } else {
+ mFrames.reset(new AnimationFrameDiscardingQueue(std::move(*oldFrameQueue)));
+ }
+}
+
+void AnimationSurfaceProvider::AnnounceSurfaceAvailable() {
+ mFramesMutex.AssertNotCurrentThreadOwns();
+ MOZ_ASSERT(mImage);
+
+ // We just got the first frame; let the surface cache know. We deliberately do
+ // this outside of mFramesMutex to avoid a potential deadlock with
+ // AddSizeOfExcludingThis(), since otherwise we'd be acquiring mFramesMutex
+ // and then the surface cache lock, while the memory reporting code would
+ // acquire the surface cache lock and then mFramesMutex.
+ SurfaceCache::SurfaceAvailable(WrapNotNull(this));
+}
+
+void AnimationSurfaceProvider::FinishDecoding() {
+ mDecodingMutex.AssertCurrentThreadOwns();
+ MOZ_ASSERT(mDecoder);
+
+ if (mImage) {
+ // Send notifications.
+ NotifyDecodeComplete(WrapNotNull(mImage), WrapNotNull(mDecoder));
+ }
+
+ // Determine if we need to recreate the decoder, in case we are discarding
+ // frames and need to loop back to the beginning.
+ bool recreateDecoder;
+ {
+ MutexAutoLock lock(mFramesMutex);
+ recreateDecoder = !mFrames->HasRedecodeError() && mFrames->MayDiscard();
+ }
+
+ if (recreateDecoder) {
+ mDecoder = DecoderFactory::CloneAnimationDecoder(mDecoder);
+ MOZ_ASSERT(mDecoder);
+ } else {
+ mDecoder = nullptr;
+ }
+
+ // We don't need a reference to our image anymore, either, and we don't want
+ // one. We may be stored in the surface cache for a long time after decoding
+ // finishes. If we don't drop our reference to the image, we'll end up
+ // keeping it alive as long as we remain in the surface cache, which could
+ // greatly extend the image's lifetime - in fact, if the image isn't
+ // discardable, it'd result in a leak!
+ DropImageReference();
+}
+
+bool AnimationSurfaceProvider::ShouldPreferSyncRun() const {
+ MutexAutoLock lock(mDecodingMutex);
+ MOZ_ASSERT(mDecoder);
+
+ return mDecoder->ShouldSyncDecode(
+ StaticPrefs::image_mem_decode_bytes_at_a_time_AtStartup());
+}
+
+RawAccessFrameRef AnimationSurfaceProvider::RecycleFrame(
+ gfx::IntRect& aRecycleRect) {
+ MutexAutoLock lock(mFramesMutex);
+ MOZ_ASSERT(mFrames->IsRecycling());
+ return mFrames->RecycleFrame(aRecycleRect);
+}
+
+nsresult AnimationSurfaceProvider::UpdateKey(
+ layers::RenderRootStateManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources, wr::ImageKey& aKey) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ RefPtr<SourceSurface> surface;
+ {
+ MutexAutoLock lock(mFramesMutex);
+ imgFrame* frame =
+ mFrames->Get(mFrames->Displayed(), /* aForDisplay */ true);
+ if (!frame) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ surface = frame->GetSourceSurface();
+ }
+
+ mCompositedFrameRequested = true;
+ auto* sharedSurface = static_cast<SourceSurfaceSharedData*>(surface.get());
+ return mSharedAnimation->UpdateKey(sharedSurface, aManager, aResources, aKey);
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/AnimationSurfaceProvider.h b/image/AnimationSurfaceProvider.h
new file mode 100644
index 0000000000..920638279e
--- /dev/null
+++ b/image/AnimationSurfaceProvider.h
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * An ISurfaceProvider for animated images.
+ */
+
+#ifndef mozilla_image_AnimationSurfaceProvider_h
+#define mozilla_image_AnimationSurfaceProvider_h
+
+#include "mozilla/UniquePtr.h"
+
+#include "Decoder.h"
+#include "FrameAnimator.h"
+#include "IDecodingTask.h"
+#include "ISurfaceProvider.h"
+#include "AnimationFrameBuffer.h"
+
+namespace mozilla {
+namespace layers {
+class SharedSurfacesAnimation;
+}
+
+namespace image {
+
+/**
+ * An ISurfaceProvider that manages the decoding of animated images and
+ * dynamically generates surfaces for the current playback state of the
+ * animation.
+ */
+class AnimationSurfaceProvider final : public ISurfaceProvider,
+ public IDecodingTask,
+ public IDecoderFrameRecycler {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AnimationSurfaceProvider, override)
+
+ AnimationSurfaceProvider(NotNull<RasterImage*> aImage,
+ const SurfaceKey& aSurfaceKey,
+ NotNull<Decoder*> aDecoder, size_t aCurrentFrame);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // ISurfaceProvider implementation.
+ //////////////////////////////////////////////////////////////////////////////
+
+ public:
+ bool IsFinished() const override;
+ bool IsFullyDecoded() const override;
+ size_t LogicalSizeInBytes() const override;
+ void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
+ const AddSizeOfCb& aCallback) override;
+ void Reset() override;
+ void Advance(size_t aFrame) override;
+ bool MayAdvance() const override { return mCompositedFrameRequested; }
+ void MarkMayAdvance() override { mCompositedFrameRequested = true; }
+
+ protected:
+ DrawableFrameRef DrawableRef(size_t aFrame) override;
+ already_AddRefed<imgFrame> GetFrame(size_t aFrame) override;
+
+ // Animation frames are always locked. This is because we only want to release
+ // their memory atomically (due to the surface cache discarding them). If they
+ // were unlocked, the OS could end up releasing the memory of random frames
+ // from the middle of the animation, which is not worth the complexity of
+ // dealing with.
+ bool IsLocked() const override { return true; }
+ void SetLocked(bool) override {}
+
+ //////////////////////////////////////////////////////////////////////////////
+ // IDecodingTask implementation.
+ //////////////////////////////////////////////////////////////////////////////
+
+ public:
+ void Run() override;
+ bool ShouldPreferSyncRun() const override;
+
+ // Full decodes are low priority compared to metadata decodes because they
+ // don't block layout or page load.
+ TaskPriority Priority() const override { return TaskPriority::eLow; }
+
+ //////////////////////////////////////////////////////////////////////////////
+ // IDecoderFrameRecycler implementation.
+ //////////////////////////////////////////////////////////////////////////////
+
+ public:
+ RawAccessFrameRef RecycleFrame(gfx::IntRect& aRecycleRect) override;
+
+ //////////////////////////////////////////////////////////////////////////////
+ // IDecoderFrameRecycler implementation.
+ //////////////////////////////////////////////////////////////////////////////
+
+ public:
+ nsresult UpdateKey(layers::RenderRootStateManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources,
+ wr::ImageKey& aKey) override;
+
+ private:
+ virtual ~AnimationSurfaceProvider();
+
+ void DropImageReference();
+ void AnnounceSurfaceAvailable();
+ void FinishDecoding();
+ void RequestFrameDiscarding();
+
+ // @returns Whether or not we should continue decoding.
+ bool CheckForNewFrameAtYield();
+
+ // @returns Whether or not we should restart decoding.
+ bool CheckForNewFrameAtTerminalState();
+
+ /// The image associated with our decoder.
+ RefPtr<RasterImage> mImage;
+
+ /// A mutex to protect mDecoder. Always taken before mFramesMutex.
+ mutable Mutex mDecodingMutex MOZ_UNANNOTATED;
+
+ /// The decoder used to decode this animation.
+ RefPtr<Decoder> mDecoder;
+
+ /// A mutex to protect mFrames. Always taken after mDecodingMutex.
+ mutable Mutex mFramesMutex MOZ_UNANNOTATED;
+
+ /// The frames of this animation, in order.
+ UniquePtr<AnimationFrameBuffer> mFrames;
+
+ /// Whether the current frame was requested for display since the last time we
+ /// advanced the animation.
+ bool mCompositedFrameRequested;
+
+ ///
+ RefPtr<layers::SharedSurfacesAnimation> mSharedAnimation;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_AnimationSurfaceProvider_h
diff --git a/image/AutoRestoreSVGState.h b/image/AutoRestoreSVGState.h
new file mode 100644
index 0000000000..c01c2f612b
--- /dev/null
+++ b/image/AutoRestoreSVGState.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_AutoRestoreSVGState_h
+#define mozilla_image_AutoRestoreSVGState_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/AutoRestore.h"
+#include "mozilla/SVGContextPaint.h"
+#include "mozilla/dom/SVGSVGElement.h"
+#include "nsPresContext.h"
+#include "SVGDrawingParameters.h"
+#include "SVGDocumentWrapper.h"
+#include "mozilla/dom/DocumentInlines.h"
+#include "mozilla/dom/SVGDocument.h"
+#include "mozilla/dom/BrowsingContextBinding.h"
+
+namespace mozilla::image {
+
+class MOZ_STACK_CLASS AutoRestoreSVGState final {
+ public:
+ AutoRestoreSVGState(const SVGDrawingParameters& aParams,
+ SVGDocumentWrapper* aSVGDocumentWrapper,
+ bool aContextPaint)
+ : AutoRestoreSVGState(aParams.svgContext, aParams.animationTime,
+ aSVGDocumentWrapper, aContextPaint) {}
+
+ AutoRestoreSVGState(const SVGImageContext& aSVGContext, float aAnimationTime,
+ SVGDocumentWrapper* aSVGDocumentWrapper,
+ bool aContextPaint)
+ : mIsDrawing(aSVGDocumentWrapper->mIsDrawing),
+ // Apply any 'preserveAspectRatio' override (if specified) to the root
+ // element:
+ mPAR(aSVGContext, aSVGDocumentWrapper->GetRootSVGElem()),
+ // Set the animation time:
+ mTime(aSVGDocumentWrapper->GetRootSVGElem(), aAnimationTime) {
+ MOZ_ASSERT(!mIsDrawing.SavedValue());
+ MOZ_ASSERT(aSVGDocumentWrapper->GetDocument());
+
+ if (auto* pc = aSVGDocumentWrapper->GetDocument()->GetPresContext()) {
+ pc->SetColorSchemeOverride([&] {
+ if (auto scheme = aSVGContext.GetColorScheme()) {
+ return *scheme == ColorScheme::Light
+ ? dom::PrefersColorSchemeOverride::Light
+ : dom::PrefersColorSchemeOverride::Dark;
+ }
+ return dom::PrefersColorSchemeOverride::None;
+ }());
+ }
+
+ aSVGDocumentWrapper->mIsDrawing = true;
+
+ // Set context paint (if specified) on the document:
+ if (aContextPaint) {
+ MOZ_ASSERT(aSVGContext.GetContextPaint());
+ mContextPaint.emplace(aSVGContext.GetContextPaint(),
+ aSVGDocumentWrapper->GetDocument());
+ }
+ }
+
+ private:
+ AutoRestore<bool> mIsDrawing;
+ AutoPreserveAspectRatioOverride mPAR;
+ AutoSVGTimeSetRestore mTime;
+ Maybe<AutoSetRestoreSVGContextPaint> mContextPaint;
+};
+
+} // namespace mozilla::image
+
+#endif // mozilla_image_AutoRestoreSVGState_h
diff --git a/image/BMPHeaders.h b/image/BMPHeaders.h
new file mode 100644
index 0000000000..2b58f6054c
--- /dev/null
+++ b/image/BMPHeaders.h
@@ -0,0 +1,53 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_BMPHeaders_h
+#define mozilla_image_BMPHeaders_h
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace mozilla {
+namespace image {
+namespace bmp {
+
+// The length of the file header as defined in the BMP spec.
+static const size_t FILE_HEADER_LENGTH = 14;
+
+// This lengths of the info header for the different BMP versions.
+struct InfoHeaderLength {
+ enum {
+ WIN_V2 = 12,
+ WIN_V3 = 40,
+ WIN_V4 = 108,
+ WIN_V5 = 124,
+
+ // OS2_V1 is omitted; it's the same as WIN_V2.
+ OS2_V2_MIN = 16, // Minimum allowed value for OS2v2.
+ OS2_V2_MAX = 64, // Maximum allowed value for OS2v2.
+
+ WIN_ICO = WIN_V3,
+ };
+};
+
+enum class InfoColorSpace : uint32_t {
+ CALIBRATED_RGB = 0x00000000,
+ SRGB = 0x73524742,
+ WIN = 0x57696E20,
+ LINKED = 0x4C494E4B,
+ EMBEDDED = 0x4D424544,
+};
+
+enum class InfoColorIntent : uint32_t {
+ BUSINESS = 0x00000001,
+ GRAPHICS = 0x00000002,
+ IMAGES = 0x00000004,
+ ABS_COLORIMETRIC = 0x00000008,
+};
+
+} // namespace bmp
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_BMPHeaders_h
diff --git a/image/BlobSurfaceProvider.cpp b/image/BlobSurfaceProvider.cpp
new file mode 100644
index 0000000000..1e9e8dacca
--- /dev/null
+++ b/image/BlobSurfaceProvider.cpp
@@ -0,0 +1,310 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "BlobSurfaceProvider.h"
+#include "AutoRestoreSVGState.h"
+#include "ImageRegion.h"
+#include "SVGDocumentWrapper.h"
+#include "mozilla/PresShell.h"
+#include "mozilla/dom/Document.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/layers/IpcResourceUpdateQueue.h"
+#include "mozilla/layers/WebRenderBridgeChild.h"
+#include "mozilla/layers/WebRenderDrawEventRecorder.h"
+
+using namespace mozilla::gfx;
+using namespace mozilla::layers;
+
+namespace mozilla::image {
+
+BlobSurfaceProvider::BlobSurfaceProvider(
+ const ImageKey aImageKey, const SurfaceKey& aSurfaceKey,
+ image::SVGDocumentWrapper* aSVGDocumentWrapper, uint32_t aImageFlags)
+ : ISurfaceProvider(aImageKey, aSurfaceKey,
+ AvailabilityState::StartAvailable()),
+ mSVGDocumentWrapper(aSVGDocumentWrapper),
+ mImageFlags(aImageFlags) {
+ MOZ_ASSERT(mSVGDocumentWrapper);
+ MOZ_ASSERT(aImageFlags & imgIContainer::FLAG_RECORD_BLOB);
+}
+
+BlobSurfaceProvider::~BlobSurfaceProvider() {
+ if (NS_IsMainThread()) {
+ DestroyKeys(mKeys);
+ return;
+ }
+
+ NS_ReleaseOnMainThread("SourceSurfaceBlobImage::mSVGDocumentWrapper",
+ mSVGDocumentWrapper.forget());
+ NS_DispatchToMainThread(
+ NS_NewRunnableFunction("SourceSurfaceBlobImage::DestroyKeys",
+ [keys = std::move(mKeys)] { DestroyKeys(keys); }));
+}
+
+/* static */ void BlobSurfaceProvider::DestroyKeys(
+ const AutoTArray<BlobImageKeyData, 1>& aKeys) {
+ for (const auto& entry : aKeys) {
+ if (entry.mManager->IsDestroyed()) {
+ continue;
+ }
+
+ WebRenderBridgeChild* wrBridge = entry.mManager->WrBridge();
+ if (!wrBridge || !wrBridge->MatchesNamespace(entry.mBlobKey)) {
+ continue;
+ }
+
+ entry.mManager->GetRenderRootStateManager()->AddBlobImageKeyForDiscard(
+ entry.mBlobKey);
+ }
+}
+
+nsresult BlobSurfaceProvider::UpdateKey(
+ layers::RenderRootStateManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources, wr::ImageKey& aKey) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ layers::WebRenderLayerManager* manager = aManager->LayerManager();
+ MOZ_ASSERT(manager);
+
+ Maybe<wr::BlobImageKey> key;
+ auto i = mKeys.Length();
+ while (i > 0) {
+ --i;
+ BlobImageKeyData& entry = mKeys[i];
+ if (entry.mManager->IsDestroyed()) {
+ mKeys.RemoveElementAt(i);
+ } else if (entry.mManager == manager) {
+ WebRenderBridgeChild* wrBridge = manager->WrBridge();
+ MOZ_ASSERT(wrBridge);
+
+ bool ownsKey = wrBridge->MatchesNamespace(entry.mBlobKey);
+ if (ownsKey && !entry.mDirty) {
+ key.emplace(entry.mBlobKey);
+ continue;
+ }
+
+ // Even if the manager is the same, its underlying WebRenderBridgeChild
+ // can change state. Either our namespace differs, and our old key has
+ // already been discarded, or the blob has changed. Either way, we need
+ // to rerecord it.
+ auto newEntry = RecordDrawing(manager, aResources,
+ ownsKey ? Some(entry.mBlobKey) : Nothing());
+ if (!newEntry) {
+ if (ownsKey) {
+ aManager->AddBlobImageKeyForDiscard(entry.mBlobKey);
+ }
+ mKeys.RemoveElementAt(i);
+ continue;
+ }
+
+ key.emplace(newEntry.ref().mBlobKey);
+ entry = std::move(newEntry.ref());
+ MOZ_ASSERT(!entry.mDirty);
+ }
+ }
+
+ // We didn't find an entry. Attempt to record the blob with a new key.
+ if (!key) {
+ auto newEntry = RecordDrawing(manager, aResources, Nothing());
+ if (newEntry) {
+ key.emplace(newEntry.ref().mBlobKey);
+ mKeys.AppendElement(std::move(newEntry.ref()));
+ }
+ }
+
+ if (key) {
+ aKey = wr::AsImageKey(key.value());
+ return NS_OK;
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+void BlobSurfaceProvider::InvalidateRecording() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ auto i = mKeys.Length();
+ while (i > 0) {
+ --i;
+ BlobImageKeyData& entry = mKeys[i];
+ if (entry.mManager->IsDestroyed()) {
+ mKeys.RemoveElementAt(i);
+ } else {
+ entry.mDirty = true;
+ }
+ }
+}
+
+Maybe<BlobImageKeyData> BlobSurfaceProvider::RecordDrawing(
+ WebRenderLayerManager* aManager, wr::IpcResourceUpdateQueue& aResources,
+ Maybe<wr::BlobImageKey> aBlobKey) {
+ MOZ_ASSERT(!aManager->IsDestroyed());
+
+ if (mSVGDocumentWrapper->IsDrawing()) {
+ return Nothing();
+ }
+
+ // This is either our first pass, or we have a stale key requiring us to
+ // re-record the SVG image draw commands.
+ auto* rootManager = aManager->GetRenderRootStateManager();
+ auto* wrBridge = aManager->WrBridge();
+
+ const auto& size = GetSurfaceKey().Size();
+ const auto& region = GetSurfaceKey().Region();
+ const auto& svgContext = GetSurfaceKey().SVGContext();
+
+ IntRect imageRect = region ? region->Rect() : IntRect(IntPoint(0, 0), size);
+ IntRect imageRectOrigin = imageRect - imageRect.TopLeft();
+
+ std::vector<RefPtr<ScaledFont>> fonts;
+ bool validFonts = true;
+ RefPtr<WebRenderDrawEventRecorder> recorder =
+ MakeAndAddRef<WebRenderDrawEventRecorder>(
+ [&](MemStream& aStream,
+ std::vector<RefPtr<ScaledFont>>& aScaledFonts) {
+ auto count = aScaledFonts.size();
+ aStream.write((const char*)&count, sizeof(count));
+
+ for (auto& scaled : aScaledFonts) {
+ Maybe<wr::FontInstanceKey> key =
+ wrBridge->GetFontKeyForScaledFont(scaled, aResources);
+ if (key.isNothing()) {
+ validFonts = false;
+ break;
+ }
+ BlobFont font = {key.value(), scaled};
+ aStream.write((const char*)&font, sizeof(font));
+ }
+
+ fonts = std::move(aScaledFonts);
+ });
+
+ RefPtr<DrawTarget> dummyDt =
+ gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
+ RefPtr<DrawTarget> dt =
+ Factory::CreateRecordingDrawTarget(recorder, dummyDt, imageRectOrigin);
+
+ if (!dt || !dt->IsValid()) {
+ return Nothing();
+ }
+
+ bool contextPaint = svgContext.GetContextPaint();
+
+ float animTime = (GetSurfaceKey().Playback() == PlaybackType::eStatic)
+ ? 0.0f
+ : mSVGDocumentWrapper->GetCurrentTimeAsFloat();
+
+ IntSize viewportSize = size;
+ if (auto cssViewportSize = svgContext.GetViewportSize()) {
+ // XXX losing unit
+ viewportSize.SizeTo(cssViewportSize->width, cssViewportSize->height);
+ }
+
+ {
+ // Get (& sanity-check) the helper-doc's presShell
+ RefPtr<PresShell> presShell = mSVGDocumentWrapper->GetPresShell();
+ MOZ_ASSERT(presShell, "GetPresShell returned null for an SVG image?");
+
+ nsPresContext* presContext = presShell->GetPresContext();
+ MOZ_ASSERT(presContext, "pres shell w/out pres context");
+
+ auto* doc = presShell->GetDocument();
+ [[maybe_unused]] nsIURI* uri = doc ? doc->GetDocumentURI() : nullptr;
+ AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(
+ "SVG Image recording", GRAPHICS,
+ nsPrintfCString("(%d,%d) %dx%d from %dx%d %s", imageRect.x, imageRect.y,
+ imageRect.width, imageRect.height, size.width,
+ size.height,
+ uri ? uri->GetSpecOrDefault().get() : "N/A"));
+
+ AutoRestoreSVGState autoRestore(svgContext, animTime, mSVGDocumentWrapper,
+ contextPaint);
+
+ mSVGDocumentWrapper->UpdateViewportBounds(viewportSize);
+ mSVGDocumentWrapper->FlushImageTransformInvalidation();
+
+ gfxContext ctx(dt);
+
+ nsRect svgRect;
+ auto auPerDevPixel = presContext->AppUnitsPerDevPixel();
+ if (size != viewportSize) {
+ auto scaleX = double(size.width) / viewportSize.width;
+ auto scaleY = double(size.height) / viewportSize.height;
+ ctx.SetMatrix(Matrix::Scaling(float(scaleX), float(scaleY)));
+
+ auto scaledVisibleRect = IntRectToRect(imageRect);
+ scaledVisibleRect.Scale(float(auPerDevPixel / scaleX),
+ float(auPerDevPixel / scaleY));
+ scaledVisibleRect.Round();
+ svgRect.SetRect(
+ int32_t(scaledVisibleRect.x), int32_t(scaledVisibleRect.y),
+ int32_t(scaledVisibleRect.width), int32_t(scaledVisibleRect.height));
+ } else {
+ auto scaledVisibleRect(imageRect);
+ scaledVisibleRect.Scale(auPerDevPixel);
+ svgRect.SetRect(scaledVisibleRect.x, scaledVisibleRect.y,
+ scaledVisibleRect.width, scaledVisibleRect.height);
+ }
+
+ RenderDocumentFlags renderDocFlags =
+ RenderDocumentFlags::IgnoreViewportScrolling;
+ if (!(mImageFlags & imgIContainer::FLAG_SYNC_DECODE)) {
+ renderDocFlags |= RenderDocumentFlags::AsyncDecodeImages;
+ }
+ if (mImageFlags & imgIContainer::FLAG_HIGH_QUALITY_SCALING) {
+ renderDocFlags |= RenderDocumentFlags::UseHighQualityScaling;
+ }
+
+ presShell->RenderDocument(svgRect, renderDocFlags,
+ NS_RGBA(0, 0, 0, 0), // transparent
+ &ctx);
+ }
+
+ recorder->FlushItem(imageRectOrigin);
+ recorder->Finish();
+
+ if (!validFonts) {
+ gfxCriticalNote << "Failed serializing fonts for blob vector image";
+ return Nothing();
+ }
+
+ Range<uint8_t> bytes((uint8_t*)recorder->mOutputStream.mData,
+ recorder->mOutputStream.mLength);
+ wr::BlobImageKey key = aBlobKey
+ ? aBlobKey.value()
+ : wr::BlobImageKey{wrBridge->GetNextImageKey()};
+ wr::ImageDescriptor descriptor(imageRect.Size(), 0, SurfaceFormat::OS_RGBA,
+ wr::OpacityType::HasAlphaChannel);
+
+ auto visibleRect = ImageIntRect::FromUnknownRect(imageRectOrigin);
+ if (aBlobKey) {
+ if (!aResources.UpdateBlobImage(key, descriptor, bytes, visibleRect,
+ visibleRect)) {
+ return Nothing();
+ }
+ } else if (!aResources.AddBlobImage(key, descriptor, bytes, visibleRect)) {
+ return Nothing();
+ }
+
+ std::vector<RefPtr<SourceSurface>> externalSurfaces;
+ recorder->TakeExternalSurfaces(externalSurfaces);
+
+ for (auto& surface : externalSurfaces) {
+ // While we don't use the image key with the surface, because the blob image
+ // renderer doesn't have easy access to the resource set, we still want to
+ // ensure one is generated. That will ensure the surface remains alive until
+ // at least the last epoch which the blob image could be used in.
+ wr::ImageKey key = {};
+ DebugOnly<nsresult> rv =
+ SharedSurfacesChild::Share(surface, rootManager, aResources, key);
+ MOZ_ASSERT(rv.value != NS_ERROR_NOT_IMPLEMENTED);
+ }
+
+ return Some(BlobImageKeyData(aManager, key, std::move(fonts),
+ std::move(externalSurfaces)));
+}
+
+} // namespace mozilla::image
diff --git a/image/BlobSurfaceProvider.h b/image/BlobSurfaceProvider.h
new file mode 100644
index 0000000000..6515bb2af4
--- /dev/null
+++ b/image/BlobSurfaceProvider.h
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MOZILLA_IMAGE_BLOBSURFACEPROVIDER_H_
+#define MOZILLA_IMAGE_BLOBSURFACEPROVIDER_H_
+
+#include "mozilla/Maybe.h"
+#include "mozilla/SVGImageContext.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/layers/WebRenderLayerManager.h"
+#include "ImageRegion.h"
+#include "ISurfaceProvider.h"
+
+#include <vector>
+
+namespace mozilla {
+namespace image {
+
+class BlobImageKeyData final {
+ public:
+ BlobImageKeyData(layers::WebRenderLayerManager* aManager,
+ const wr::BlobImageKey& aBlobKey,
+ std::vector<RefPtr<gfx::ScaledFont>>&& aScaledFonts,
+ std::vector<RefPtr<gfx::SourceSurface>>&& aExternalSurfaces)
+ : mManager(aManager),
+ mBlobKey(aBlobKey),
+ mScaledFonts(std::move(aScaledFonts)),
+ mExternalSurfaces(std::move(aExternalSurfaces)),
+ mDirty(false) {}
+
+ BlobImageKeyData(BlobImageKeyData&& aOther) noexcept
+ : mManager(std::move(aOther.mManager)),
+ mBlobKey(aOther.mBlobKey),
+ mScaledFonts(std::move(aOther.mScaledFonts)),
+ mExternalSurfaces(std::move(aOther.mExternalSurfaces)),
+ mDirty(aOther.mDirty) {}
+
+ BlobImageKeyData& operator=(BlobImageKeyData&& aOther) noexcept {
+ mManager = std::move(aOther.mManager);
+ mBlobKey = aOther.mBlobKey;
+ mScaledFonts = std::move(aOther.mScaledFonts);
+ mExternalSurfaces = std::move(aOther.mExternalSurfaces);
+ mDirty = aOther.mDirty;
+ return *this;
+ }
+
+ BlobImageKeyData(const BlobImageKeyData&) = delete;
+ BlobImageKeyData& operator=(const BlobImageKeyData&) = delete;
+
+ RefPtr<layers::WebRenderLayerManager> mManager;
+ wr::BlobImageKey mBlobKey;
+ std::vector<RefPtr<gfx::ScaledFont>> mScaledFonts;
+ std::vector<RefPtr<gfx::SourceSurface>> mExternalSurfaces;
+ bool mDirty;
+};
+
+} // namespace image
+} // namespace mozilla
+
+MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR(mozilla::image::BlobImageKeyData);
+
+namespace mozilla {
+namespace wr {
+class IpcResourceUpdateQueue;
+} // namespace wr
+
+namespace image {
+class SVGDocumentWrapper;
+
+/**
+ * An ISurfaceProvider that manages blob recordings of SVG images. Unlike the
+ * rasterized ISurfaceProviders, it only provides a recording which may be
+ * replayed in the compositor process by WebRender. It may be invalidated
+ * directly in order to reuse the resource ids and underlying buffers when the
+ * SVG image has changed (e.g. it is animated).
+ */
+class BlobSurfaceProvider final : public ISurfaceProvider {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BlobSurfaceProvider, override)
+
+ BlobSurfaceProvider(ImageKey aImageKey, const SurfaceKey& aSurfaceKey,
+ SVGDocumentWrapper* aSVGDocumentWrapper,
+ uint32_t aImageFlags);
+
+ bool IsFinished() const override { return true; }
+
+ size_t LogicalSizeInBytes() const override {
+ const gfx::IntSize& size = GetSurfaceKey().Size();
+ return size.width * size.height * sizeof(uint32_t);
+ }
+
+ nsresult UpdateKey(layers::RenderRootStateManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources,
+ wr::ImageKey& aKey) override;
+
+ void InvalidateRecording() override;
+
+ void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
+ const AddSizeOfCb& aCallback) override {
+ AddSizeOfCbData metadata;
+ metadata.mFinished = true;
+ metadata.mHeapBytes += mKeys.ShallowSizeOfExcludingThis(aMallocSizeOf);
+
+ gfx::SourceSurface::SizeOfInfo info;
+ info.AddType(gfx::SurfaceType::BLOB_IMAGE);
+ metadata.Accumulate(info);
+
+ aCallback(metadata);
+ }
+
+ protected:
+ DrawableFrameRef DrawableRef(size_t aFrame) override {
+ MOZ_ASSERT_UNREACHABLE("BlobSurfaceProvider::DrawableRef not supported!");
+ return DrawableFrameRef();
+ }
+ bool IsLocked() const override { return true; }
+ void SetLocked(bool) override {}
+
+ private:
+ ~BlobSurfaceProvider() override;
+
+ Maybe<BlobImageKeyData> RecordDrawing(layers::WebRenderLayerManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources,
+ Maybe<wr::BlobImageKey> aBlobKey);
+
+ static void DestroyKeys(const AutoTArray<BlobImageKeyData, 1>& aKeys);
+
+ AutoTArray<BlobImageKeyData, 1> mKeys;
+
+ RefPtr<image::SVGDocumentWrapper> mSVGDocumentWrapper;
+ uint32_t mImageFlags;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif /* MOZILLA_IMAGE_BLOBSURFACEPROVIDER_H_ */
diff --git a/image/ClippedImage.cpp b/image/ClippedImage.cpp
new file mode 100644
index 0000000000..cad74ebdf8
--- /dev/null
+++ b/image/ClippedImage.cpp
@@ -0,0 +1,512 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ClippedImage.h"
+
+#include <algorithm>
+#include <cmath>
+#include <new> // Workaround for bug in VS10; see bug 981264.
+#include <utility>
+
+#include "ImageRegion.h"
+#include "Orientation.h"
+#include "gfxContext.h"
+#include "gfxDrawable.h"
+#include "gfxPlatform.h"
+#include "gfxUtils.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/SVGImageContext.h"
+
+#include "mozilla/gfx/2D.h"
+
+namespace mozilla {
+
+using namespace gfx;
+using std::max;
+
+namespace image {
+
+class ClippedImageCachedSurface {
+ public:
+ ClippedImageCachedSurface(already_AddRefed<SourceSurface> aSurface,
+ const nsIntSize& aSize,
+ const SVGImageContext& aSVGContext, float aFrame,
+ uint32_t aFlags, ImgDrawResult aDrawResult)
+ : mSurface(aSurface),
+ mSize(aSize),
+ mSVGContext(aSVGContext),
+ mFrame(aFrame),
+ mFlags(aFlags),
+ mDrawResult(aDrawResult) {
+ MOZ_ASSERT(mSurface, "Must have a valid surface");
+ }
+
+ bool Matches(const nsIntSize& aSize, const SVGImageContext& aSVGContext,
+ float aFrame, uint32_t aFlags) const {
+ return mSize == aSize && mSVGContext == aSVGContext && mFrame == aFrame &&
+ mFlags == aFlags;
+ }
+
+ already_AddRefed<SourceSurface> Surface() const {
+ RefPtr<SourceSurface> surf(mSurface);
+ return surf.forget();
+ }
+
+ ImgDrawResult GetDrawResult() const { return mDrawResult; }
+
+ bool NeedsRedraw() const {
+ return mDrawResult != ImgDrawResult::SUCCESS &&
+ mDrawResult != ImgDrawResult::BAD_IMAGE;
+ }
+
+ private:
+ RefPtr<SourceSurface> mSurface;
+ const nsIntSize mSize;
+ SVGImageContext mSVGContext;
+ const float mFrame;
+ const uint32_t mFlags;
+ const ImgDrawResult mDrawResult;
+};
+
+class DrawSingleTileCallback : public gfxDrawingCallback {
+ public:
+ DrawSingleTileCallback(ClippedImage* aImage, const nsIntSize& aSize,
+ const SVGImageContext& aSVGContext,
+ uint32_t aWhichFrame, uint32_t aFlags, float aOpacity)
+ : mImage(aImage),
+ mSize(aSize),
+ mSVGContext(aSVGContext),
+ mWhichFrame(aWhichFrame),
+ mFlags(aFlags),
+ mDrawResult(ImgDrawResult::NOT_READY),
+ mOpacity(aOpacity) {
+ MOZ_ASSERT(mImage, "Must have an image to clip");
+ }
+
+ virtual bool operator()(gfxContext* aContext, const gfxRect& aFillRect,
+ const SamplingFilter aSamplingFilter,
+ const gfxMatrix& aTransform) override {
+ MOZ_ASSERT(aTransform.IsIdentity(),
+ "Caller is probably CreateSamplingRestrictedDrawable, "
+ "which should not happen");
+
+ // Draw the image. |gfxCallbackDrawable| always calls this function with
+ // arguments that guarantee we never tile.
+ mDrawResult = mImage->DrawSingleTile(
+ aContext, mSize, ImageRegion::Create(aFillRect), mWhichFrame,
+ aSamplingFilter, mSVGContext, mFlags, mOpacity);
+
+ return true;
+ }
+
+ ImgDrawResult GetDrawResult() { return mDrawResult; }
+
+ private:
+ RefPtr<ClippedImage> mImage;
+ const nsIntSize mSize;
+ const SVGImageContext& mSVGContext;
+ const uint32_t mWhichFrame;
+ const uint32_t mFlags;
+ ImgDrawResult mDrawResult;
+ float mOpacity;
+};
+
+ClippedImage::ClippedImage(Image* aImage, nsIntRect aClip,
+ const Maybe<nsSize>& aSVGViewportSize)
+ : ImageWrapper(aImage), mClip(aClip) {
+ MOZ_ASSERT(aImage != nullptr, "ClippedImage requires an existing Image");
+ MOZ_ASSERT_IF(aSVGViewportSize,
+ aImage->GetType() == imgIContainer::TYPE_VECTOR);
+ if (aSVGViewportSize) {
+ mSVGViewportSize =
+ Some(aSVGViewportSize->ToNearestPixels(AppUnitsPerCSSPixel()));
+ }
+}
+
+ClippedImage::~ClippedImage() {}
+
+bool ClippedImage::ShouldClip() {
+ // We need to evaluate the clipping region against the image's width and
+ // height once they're available to determine if it's valid and whether we
+ // actually need to do any work. We may fail if the image's width and height
+ // aren't available yet, in which case we'll try again later.
+ if (mShouldClip.isNothing()) {
+ int32_t width, height;
+ RefPtr<ProgressTracker> progressTracker =
+ InnerImage()->GetProgressTracker();
+ if (InnerImage()->HasError()) {
+ // If there's a problem with the inner image we'll let it handle
+ // everything.
+ mShouldClip.emplace(false);
+ } else if (mSVGViewportSize && !mSVGViewportSize->IsEmpty()) {
+ // Clamp the clipping region to the size of the SVG viewport.
+ nsIntRect svgViewportRect(nsIntPoint(0, 0), *mSVGViewportSize);
+
+ mClip = mClip.Intersect(svgViewportRect);
+
+ // If the clipping region is the same size as the SVG viewport size
+ // we don't have to do anything.
+ mShouldClip.emplace(!mClip.IsEqualInterior(svgViewportRect));
+ } else if (NS_SUCCEEDED(InnerImage()->GetWidth(&width)) && width > 0 &&
+ NS_SUCCEEDED(InnerImage()->GetHeight(&height)) && height > 0) {
+ // Clamp the clipping region to the size of the underlying image.
+ mClip = mClip.Intersect(nsIntRect(0, 0, width, height));
+
+ // If the clipping region is the same size as the underlying image we
+ // don't have to do anything.
+ mShouldClip.emplace(
+ !mClip.IsEqualInterior(nsIntRect(0, 0, width, height)));
+ } else if (progressTracker &&
+ !(progressTracker->GetProgress() & FLAG_LOAD_COMPLETE)) {
+ // The image just hasn't finished loading yet. We don't yet know whether
+ // clipping with be needed or not for now. Just return without memorizing
+ // anything.
+ return false;
+ } else {
+ // We have a fully loaded image without a clearly defined width and
+ // height. This can happen with SVG images.
+ mShouldClip.emplace(false);
+ }
+ }
+
+ MOZ_ASSERT(mShouldClip.isSome(), "Should have computed a result");
+ return *mShouldClip;
+}
+
+NS_IMETHODIMP
+ClippedImage::GetWidth(int32_t* aWidth) {
+ if (!ShouldClip()) {
+ return InnerImage()->GetWidth(aWidth);
+ }
+
+ *aWidth = mClip.Width();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+ClippedImage::GetHeight(int32_t* aHeight) {
+ if (!ShouldClip()) {
+ return InnerImage()->GetHeight(aHeight);
+ }
+
+ *aHeight = mClip.Height();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+ClippedImage::GetIntrinsicSize(nsSize* aSize) {
+ if (!ShouldClip()) {
+ return InnerImage()->GetIntrinsicSize(aSize);
+ }
+
+ *aSize = nsSize(mClip.Width(), mClip.Height());
+ return NS_OK;
+}
+
+Maybe<AspectRatio> ClippedImage::GetIntrinsicRatio() {
+ if (!ShouldClip()) {
+ return InnerImage()->GetIntrinsicRatio();
+ }
+
+ return Some(AspectRatio::FromSize(mClip.Width(), mClip.Height()));
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+ClippedImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) {
+ RefPtr<SourceSurface> surface;
+ std::tie(std::ignore, surface) = GetFrameInternal(
+ mClip.Size(), SVGImageContext(), Nothing(), aWhichFrame, aFlags, 1.0);
+ return surface.forget();
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+ClippedImage::GetFrameAtSize(const IntSize& aSize, uint32_t aWhichFrame,
+ uint32_t aFlags) {
+ // XXX(seth): It'd be nice to support downscale-during-decode for this case,
+ // but right now we just fall back to the intrinsic size.
+ return GetFrame(aWhichFrame, aFlags);
+}
+
+std::pair<ImgDrawResult, RefPtr<SourceSurface>> ClippedImage::GetFrameInternal(
+ const nsIntSize& aSize, const SVGImageContext& aSVGContext,
+ const Maybe<ImageIntRegion>& aRegion, uint32_t aWhichFrame, uint32_t aFlags,
+ float aOpacity) {
+ if (!ShouldClip()) {
+ RefPtr<SourceSurface> surface = InnerImage()->GetFrame(aWhichFrame, aFlags);
+ return std::make_pair(
+ surface ? ImgDrawResult::SUCCESS : ImgDrawResult::NOT_READY,
+ std::move(surface));
+ }
+
+ float frameToDraw = InnerImage()->GetFrameIndex(aWhichFrame);
+ if (!mCachedSurface ||
+ !mCachedSurface->Matches(aSize, aSVGContext, frameToDraw, aFlags) ||
+ mCachedSurface->NeedsRedraw()) {
+ // Create a surface to draw into.
+ RefPtr<DrawTarget> target =
+ gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
+ IntSize(aSize.width, aSize.height), SurfaceFormat::OS_RGBA);
+ if (!target || !target->IsValid()) {
+ NS_ERROR("Could not create a DrawTarget");
+ return std::make_pair(ImgDrawResult::TEMPORARY_ERROR,
+ RefPtr<SourceSurface>());
+ }
+
+ gfxContext ctx(target);
+
+ // Create our callback.
+ RefPtr<DrawSingleTileCallback> drawTileCallback =
+ new DrawSingleTileCallback(this, aSize, aSVGContext, aWhichFrame,
+ aFlags, aOpacity);
+ RefPtr<gfxDrawable> drawable =
+ new gfxCallbackDrawable(drawTileCallback, aSize);
+
+ // Actually draw. The callback will end up invoking DrawSingleTile.
+ gfxUtils::DrawPixelSnapped(&ctx, drawable, SizeDouble(aSize),
+ ImageRegion::Create(aSize),
+ SurfaceFormat::OS_RGBA, SamplingFilter::LINEAR,
+ imgIContainer::FLAG_CLAMP);
+
+ // Cache the resulting surface.
+ mCachedSurface = MakeUnique<ClippedImageCachedSurface>(
+ target->Snapshot(), aSize, aSVGContext, frameToDraw, aFlags,
+ drawTileCallback->GetDrawResult());
+ }
+
+ MOZ_ASSERT(mCachedSurface, "Should have a cached surface now");
+ RefPtr<SourceSurface> surface = mCachedSurface->Surface();
+ return std::make_pair(mCachedSurface->GetDrawResult(), std::move(surface));
+}
+
+NS_IMETHODIMP_(bool)
+ClippedImage::IsImageContainerAvailable(WindowRenderer* aRenderer,
+ uint32_t aFlags) {
+ if (!ShouldClip()) {
+ return InnerImage()->IsImageContainerAvailable(aRenderer, aFlags);
+ }
+ return false;
+}
+
+NS_IMETHODIMP_(ImgDrawResult)
+ClippedImage::GetImageProvider(WindowRenderer* aRenderer,
+ const gfx::IntSize& aSize,
+ const SVGImageContext& aSVGContext,
+ const Maybe<ImageIntRegion>& aRegion,
+ uint32_t aFlags,
+ WebRenderImageProvider** aProvider) {
+ // XXX(seth): We currently don't have a way of clipping the result of
+ // GetImageContainer. We work around this by always returning null, but if it
+ // ever turns out that ClippedImage is widely used on codepaths that can
+ // actually benefit from GetImageContainer, it would be a good idea to fix
+ // that method for performance reasons.
+
+ if (!ShouldClip()) {
+ return InnerImage()->GetImageProvider(aRenderer, aSize, aSVGContext,
+ aRegion, aFlags, aProvider);
+ }
+
+ return ImgDrawResult::NOT_SUPPORTED;
+}
+
+static bool MustCreateSurface(gfxContext* aContext, const nsIntSize& aSize,
+ const ImageRegion& aRegion,
+ const uint32_t aFlags) {
+ gfxRect imageRect(0, 0, aSize.width, aSize.height);
+ bool willTile = !imageRect.Contains(aRegion.Rect()) &&
+ !(aFlags & imgIContainer::FLAG_CLAMP);
+ bool willResample = aContext->CurrentMatrix().HasNonIntegerTranslation() &&
+ (willTile || !aRegion.RestrictionContains(imageRect));
+ return willTile || willResample;
+}
+
+NS_IMETHODIMP_(ImgDrawResult)
+ClippedImage::Draw(gfxContext* aContext, const nsIntSize& aSize,
+ const ImageRegion& aRegion, uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ const SVGImageContext& aSVGContext, uint32_t aFlags,
+ float aOpacity) {
+ if (!ShouldClip()) {
+ return InnerImage()->Draw(aContext, aSize, aRegion, aWhichFrame,
+ aSamplingFilter, aSVGContext, aFlags, aOpacity);
+ }
+
+ // Check for tiling. If we need to tile then we need to create a
+ // gfxCallbackDrawable to handle drawing for us.
+ if (MustCreateSurface(aContext, aSize, aRegion, aFlags)) {
+ // Create a temporary surface containing a single tile of this image.
+ // GetFrame will call DrawSingleTile internally.
+ auto [result, surface] = GetFrameInternal(aSize, aSVGContext, Nothing(),
+ aWhichFrame, aFlags, aOpacity);
+ if (!surface) {
+ MOZ_ASSERT(result != ImgDrawResult::SUCCESS);
+ return result;
+ }
+
+ // Create a drawable from that surface.
+ RefPtr<gfxSurfaceDrawable> drawable =
+ new gfxSurfaceDrawable(surface, aSize);
+
+ // Draw.
+ gfxUtils::DrawPixelSnapped(aContext, drawable, SizeDouble(aSize), aRegion,
+ SurfaceFormat::OS_RGBA, aSamplingFilter,
+ aOpacity);
+
+ return result;
+ }
+
+ return DrawSingleTile(aContext, aSize, aRegion, aWhichFrame, aSamplingFilter,
+ aSVGContext, aFlags, aOpacity);
+}
+
+ImgDrawResult ClippedImage::DrawSingleTile(
+ gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion,
+ uint32_t aWhichFrame, SamplingFilter aSamplingFilter,
+ const SVGImageContext& aSVGContext, uint32_t aFlags, float aOpacity) {
+ MOZ_ASSERT(!MustCreateSurface(aContext, aSize, aRegion, aFlags),
+ "Shouldn't need to create a surface");
+
+ gfxRect clip(mClip.X(), mClip.Y(), mClip.Width(), mClip.Height());
+ nsIntSize size(aSize), innerSize(aSize);
+ bool needScale = false;
+ if (mSVGViewportSize && !mSVGViewportSize->IsEmpty()) {
+ innerSize = *mSVGViewportSize;
+ needScale = true;
+ } else if (NS_SUCCEEDED(InnerImage()->GetWidth(&innerSize.width)) &&
+ NS_SUCCEEDED(InnerImage()->GetHeight(&innerSize.height))) {
+ needScale = true;
+ } else {
+ MOZ_ASSERT_UNREACHABLE(
+ "If ShouldClip() led us to draw then we should never get here");
+ }
+
+ if (needScale) {
+ double scaleX = aSize.width / clip.Width();
+ double scaleY = aSize.height / clip.Height();
+
+ // Map the clip and size to the scale requested by the caller.
+ clip.Scale(scaleX, scaleY);
+ size = innerSize;
+ size.Scale(scaleX, scaleY);
+ }
+
+ // We restrict our drawing to only the clipping region, and translate so that
+ // the clipping region is placed at the position the caller expects.
+ ImageRegion region(aRegion);
+ region.MoveBy(clip.X(), clip.Y());
+ region = region.Intersect(clip);
+
+ gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
+ aContext->Multiply(gfxMatrix::Translation(-clip.X(), -clip.Y()));
+
+ auto unclipViewport = [&](const SVGImageContext& aOldContext) {
+ // Map the viewport to the inner image. Note that we don't take the aSize
+ // parameter of imgIContainer::Draw into account, just the clipping region.
+ // The size in pixels at which the output will ultimately be drawn is
+ // irrelevant here since the purpose of the SVG viewport size is to
+ // determine what *region* of the SVG document will be drawn.
+ SVGImageContext context(aOldContext);
+ auto oldViewport = aOldContext.GetViewportSize();
+ if (oldViewport) {
+ CSSIntSize newViewport;
+ newViewport.width =
+ ceil(oldViewport->width * double(innerSize.width) / mClip.Width());
+ newViewport.height =
+ ceil(oldViewport->height * double(innerSize.height) / mClip.Height());
+ context.SetViewportSize(Some(newViewport));
+ }
+ return context;
+ };
+
+ return InnerImage()->Draw(aContext, size, region, aWhichFrame,
+ aSamplingFilter, unclipViewport(aSVGContext),
+ aFlags, aOpacity);
+}
+
+NS_IMETHODIMP
+ClippedImage::RequestDiscard() {
+ // We're very aggressive about discarding.
+ mCachedSurface = nullptr;
+
+ return InnerImage()->RequestDiscard();
+}
+
+NS_IMETHODIMP_(Orientation)
+ClippedImage::GetOrientation() {
+ // XXX(seth): This should not actually be here; this is just to work around a
+ // what appears to be a bug in MSVC's linker.
+ return InnerImage()->GetOrientation();
+}
+
+nsIntSize ClippedImage::OptimalImageSizeForDest(const gfxSize& aDest,
+ uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ uint32_t aFlags) {
+ if (!ShouldClip()) {
+ return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame,
+ aSamplingFilter, aFlags);
+ }
+
+ int32_t imgWidth, imgHeight;
+ bool needScale = false;
+ bool forceUniformScaling = false;
+ if (mSVGViewportSize && !mSVGViewportSize->IsEmpty()) {
+ imgWidth = mSVGViewportSize->width;
+ imgHeight = mSVGViewportSize->height;
+ needScale = true;
+ forceUniformScaling = (aFlags & imgIContainer::FLAG_FORCE_UNIFORM_SCALING);
+ } else if (NS_SUCCEEDED(InnerImage()->GetWidth(&imgWidth)) &&
+ NS_SUCCEEDED(InnerImage()->GetHeight(&imgHeight))) {
+ needScale = true;
+ }
+
+ if (needScale) {
+ // To avoid ugly sampling artifacts, ClippedImage needs the image size to
+ // be chosen such that the clipping region lies on pixel boundaries.
+
+ // First, we select a scale that's good for ClippedImage. An integer
+ // multiple of the size of the clipping region is always fine.
+ IntSize scale = IntSize::Ceil(aDest.width / mClip.Width(),
+ aDest.height / mClip.Height());
+
+ if (forceUniformScaling) {
+ scale.width = scale.height = max(scale.height, scale.width);
+ }
+
+ // Determine the size we'd prefer to render the inner image at, and ask the
+ // inner image what size we should actually use.
+ gfxSize desiredSize(double(imgWidth) * scale.width,
+ double(imgHeight) * scale.height);
+ nsIntSize innerDesiredSize = InnerImage()->OptimalImageSizeForDest(
+ desiredSize, aWhichFrame, aSamplingFilter, aFlags);
+
+ // To get our final result, we take the inner image's desired size and
+ // determine how large the clipped region would be at that scale. (Again, we
+ // ensure an integer multiple of the size of the clipping region.)
+ IntSize finalScale =
+ IntSize::Ceil(double(innerDesiredSize.width) / imgWidth,
+ double(innerDesiredSize.height) / imgHeight);
+ return mClip.Size() * finalScale;
+ }
+
+ MOZ_ASSERT(false,
+ "If ShouldClip() led us to draw then we should never get here");
+ return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame,
+ aSamplingFilter, aFlags);
+}
+
+NS_IMETHODIMP_(nsIntRect)
+ClippedImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect) {
+ if (!ShouldClip()) {
+ return InnerImage()->GetImageSpaceInvalidationRect(aRect);
+ }
+
+ nsIntRect rect(InnerImage()->GetImageSpaceInvalidationRect(aRect));
+ rect = rect.Intersect(mClip);
+ rect.MoveBy(-mClip.X(), -mClip.Y());
+ return rect;
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/ClippedImage.h b/image/ClippedImage.h
new file mode 100644
index 0000000000..43295a53f6
--- /dev/null
+++ b/image/ClippedImage.h
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_ClippedImage_h
+#define mozilla_image_ClippedImage_h
+
+#include "ImageWrapper.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/UniquePtr.h"
+
+#include <utility>
+
+namespace mozilla {
+namespace image {
+
+class ClippedImageCachedSurface;
+class DrawSingleTileCallback;
+
+/**
+ * An Image wrapper that clips an image against a rectangle. Right now only
+ * absolute coordinates in pixels are supported.
+ *
+ * XXX(seth): There a known (performance, not correctness) issue with
+ * GetImageContainer. See the comments for that method for more information.
+ */
+class ClippedImage : public ImageWrapper {
+ typedef gfx::SourceSurface SourceSurface;
+
+ public:
+ NS_INLINE_DECL_REFCOUNTING_INHERITED(ClippedImage, ImageWrapper)
+
+ NS_IMETHOD GetWidth(int32_t* aWidth) override;
+ NS_IMETHOD GetHeight(int32_t* aHeight) override;
+ NS_IMETHOD GetIntrinsicSize(nsSize* aSize) override;
+ Maybe<AspectRatio> GetIntrinsicRatio() override;
+ NS_IMETHOD_(already_AddRefed<SourceSurface>)
+ GetFrame(uint32_t aWhichFrame, uint32_t aFlags) override;
+ NS_IMETHOD_(already_AddRefed<SourceSurface>)
+ GetFrameAtSize(const gfx::IntSize& aSize, uint32_t aWhichFrame,
+ uint32_t aFlags) override;
+ NS_IMETHOD_(bool)
+ IsImageContainerAvailable(WindowRenderer* aRenderer,
+ uint32_t aFlags) override;
+ NS_IMETHOD_(ImgDrawResult)
+ GetImageProvider(WindowRenderer* aRenderer, const gfx::IntSize& aSize,
+ const SVGImageContext& aSVGContext,
+ const Maybe<ImageIntRegion>& aRegion, uint32_t aFlags,
+ WebRenderImageProvider** aProvider) override;
+ NS_IMETHOD_(ImgDrawResult)
+ Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion,
+ uint32_t aWhichFrame, gfx::SamplingFilter aSamplingFilter,
+ const SVGImageContext& aSVGContext, uint32_t aFlags,
+ float aOpacity) override;
+ NS_IMETHOD RequestDiscard() override;
+ NS_IMETHOD_(Orientation) GetOrientation() override;
+ NS_IMETHOD_(nsIntRect)
+ GetImageSpaceInvalidationRect(const nsIntRect& aRect) override;
+ nsIntSize OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame,
+ gfx::SamplingFilter aSamplingFilter,
+ uint32_t aFlags) override;
+
+ protected:
+ ClippedImage(Image* aImage, nsIntRect aClip,
+ const Maybe<nsSize>& aSVGViewportSize);
+
+ virtual ~ClippedImage();
+
+ private:
+ std::pair<ImgDrawResult, RefPtr<SourceSurface>> GetFrameInternal(
+ const nsIntSize& aSize, const SVGImageContext& aSVGContext,
+ const Maybe<ImageIntRegion>& aRegion, uint32_t aWhichFrame,
+ uint32_t aFlags, float aOpacity);
+ bool ShouldClip();
+ ImgDrawResult DrawSingleTile(gfxContext* aContext, const nsIntSize& aSize,
+ const ImageRegion& aRegion, uint32_t aWhichFrame,
+ gfx::SamplingFilter aSamplingFilter,
+ const SVGImageContext& aSVGContext,
+ uint32_t aFlags, float aOpacity);
+
+ // If we are forced to draw a temporary surface, we cache it here.
+ UniquePtr<ClippedImageCachedSurface> mCachedSurface;
+
+ nsIntRect mClip; // The region to clip to.
+ Maybe<bool> mShouldClip; // Memoized ShouldClip() if present.
+ Maybe<nsIntSize> mSVGViewportSize; // If we're clipping a VectorImage, this
+ // is the size of viewport of that image.
+ friend class DrawSingleTileCallback;
+ friend class ImageOps;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_ClippedImage_h
diff --git a/image/CopyOnWrite.h b/image/CopyOnWrite.h
new file mode 100644
index 0000000000..af134d581a
--- /dev/null
+++ b/image/CopyOnWrite.h
@@ -0,0 +1,247 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * CopyOnWrite<T> allows code to safely read from a data structure without
+ * worrying that reentrant code will modify it.
+ */
+
+#ifndef mozilla_image_CopyOnWrite_h
+#define mozilla_image_CopyOnWrite_h
+
+#include "mozilla/RefPtr.h"
+#include "MainThreadUtils.h"
+#include "nsISupportsImpl.h"
+
+namespace mozilla {
+namespace image {
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementation Details
+///////////////////////////////////////////////////////////////////////////////
+
+namespace detail {
+
+template <typename T>
+class CopyOnWriteValue final {
+ public:
+ NS_INLINE_DECL_REFCOUNTING(CopyOnWriteValue)
+
+ explicit CopyOnWriteValue(T* aValue)
+ : mValue(aValue), mReaders(0), mWriter(false) {}
+ explicit CopyOnWriteValue(already_AddRefed<T>& aValue)
+ : mValue(aValue), mReaders(0), mWriter(false) {}
+ explicit CopyOnWriteValue(already_AddRefed<T>&& aValue)
+ : mValue(aValue), mReaders(0), mWriter(false) {}
+ explicit CopyOnWriteValue(const RefPtr<T>& aValue)
+ : mValue(aValue), mReaders(0), mWriter(false) {}
+ explicit CopyOnWriteValue(RefPtr<T>&& aValue)
+ : mValue(aValue), mReaders(0), mWriter(false) {}
+
+ T* get() { return mValue.get(); }
+ const T* get() const { return mValue.get(); }
+
+ bool HasReaders() const { return mReaders > 0; }
+ bool HasWriter() const { return mWriter; }
+ bool HasUsers() const { return HasReaders() || HasWriter(); }
+
+ void LockForReading() {
+ MOZ_ASSERT(!HasWriter());
+ mReaders++;
+ }
+ void UnlockForReading() {
+ MOZ_ASSERT(HasReaders());
+ mReaders--;
+ }
+
+ struct MOZ_STACK_CLASS AutoReadLock {
+ explicit AutoReadLock(CopyOnWriteValue* aValue) : mValue(aValue) {
+ mValue->LockForReading();
+ }
+ ~AutoReadLock() { mValue->UnlockForReading(); }
+ CopyOnWriteValue<T>* mValue;
+ };
+
+ void LockForWriting() {
+ MOZ_ASSERT(!HasUsers());
+ mWriter = true;
+ }
+ void UnlockForWriting() {
+ MOZ_ASSERT(HasWriter());
+ mWriter = false;
+ }
+
+ struct MOZ_STACK_CLASS AutoWriteLock {
+ explicit AutoWriteLock(CopyOnWriteValue* aValue) : mValue(aValue) {
+ mValue->LockForWriting();
+ }
+ ~AutoWriteLock() { mValue->UnlockForWriting(); }
+ CopyOnWriteValue<T>* mValue;
+ };
+
+ private:
+ CopyOnWriteValue(const CopyOnWriteValue&) = delete;
+ CopyOnWriteValue(CopyOnWriteValue&&) = delete;
+
+ ~CopyOnWriteValue() {}
+
+ RefPtr<T> mValue;
+ uint64_t mReaders = 0;
+ bool mWriter = false;
+};
+
+} // namespace detail
+
+///////////////////////////////////////////////////////////////////////////////
+// Public API
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * CopyOnWrite<T> allows code to safely read from a data structure without
+ * worrying that reentrant code will modify it. If reentrant code would modify
+ * the data structure while other code is reading from it, a copy is made so
+ * that readers can continue to use the old version.
+ *
+ * Note that it's legal to nest a writer inside any number of readers, but
+ * nothing can be nested inside a writer. This is because it's assumed that the
+ * state of the contained data structure may not be consistent during the write.
+ *
+ * This is a main-thread-only data structure.
+ *
+ * To work with CopyOnWrite<T>, a type T needs to be reference counted and to
+ * support copy construction.
+ */
+template <typename T>
+class CopyOnWrite final {
+ typedef detail::CopyOnWriteValue<T> CopyOnWriteValue;
+
+ public:
+ explicit CopyOnWrite(T* aValue) : mValue(new CopyOnWriteValue(aValue)) {}
+
+ explicit CopyOnWrite(already_AddRefed<T>& aValue)
+ : mValue(new CopyOnWriteValue(aValue)) {}
+
+ explicit CopyOnWrite(already_AddRefed<T>&& aValue)
+ : mValue(new CopyOnWriteValue(aValue)) {}
+
+ explicit CopyOnWrite(const RefPtr<T>& aValue)
+ : mValue(new CopyOnWriteValue(aValue)) {}
+
+ explicit CopyOnWrite(RefPtr<T>&& aValue)
+ : mValue(new CopyOnWriteValue(aValue)) {}
+
+ /// @return true if it's safe to read at this time.
+ bool CanRead() const { return !mValue->HasWriter(); }
+
+ /**
+ * Read from the contained data structure using the function @aReader.
+ * @aReader will be passed a pointer of type |const T*|. It's not legal to
+ * call this while a writer is active.
+ *
+ * @return whatever value @aReader returns, or nothing if @aReader is a void
+ * function.
+ */
+ template <typename ReadFunc>
+ auto Read(ReadFunc aReader) const
+ -> decltype(aReader(static_cast<const T*>(nullptr))) {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(CanRead());
+
+ // Run the provided function while holding a read lock.
+ RefPtr<CopyOnWriteValue> cowValue = mValue;
+ typename CopyOnWriteValue::AutoReadLock lock(cowValue);
+ return aReader(cowValue->get());
+ }
+
+ /**
+ * Read from the contained data structure using the function @aReader.
+ * @aReader will be passed a pointer of type |const T*|. If it's currently not
+ * possible to read because a writer is currently active, @aOnError will be
+ * called instead.
+ *
+ * @return whatever value @aReader or @aOnError returns (their return types
+ * must be consistent), or nothing if the provided functions are void.
+ */
+ template <typename ReadFunc, typename ErrorFunc>
+ auto Read(ReadFunc aReader, ErrorFunc aOnError) const
+ -> decltype(aReader(static_cast<const T*>(nullptr))) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!CanRead()) {
+ return aOnError();
+ }
+
+ return Read(aReader);
+ }
+
+ /// @return true if it's safe to write at this time.
+ bool CanWrite() const { return !mValue->HasWriter(); }
+
+ /**
+ * Write to the contained data structure using the function @aWriter.
+ * @aWriter will be passed a pointer of type |T*|. It's not legal to call this
+ * while another writer is active.
+ *
+ * If readers are currently active, they will be able to continue reading from
+ * a copy of the old version of the data structure. The copy will be destroyed
+ * when all its readers finish. Later readers and writers will see the
+ * version of the data structure produced by the most recent call to Write().
+ *
+ * @return whatever value @aWriter returns, or nothing if @aWriter is a void
+ * function.
+ */
+ template <typename WriteFunc>
+ auto Write(WriteFunc aWriter) -> decltype(aWriter(static_cast<T*>(nullptr))) {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(CanWrite());
+
+ // If there are readers, we need to copy first.
+ if (mValue->HasReaders()) {
+ mValue = new CopyOnWriteValue(new T(*mValue->get()));
+ }
+
+ // Run the provided function while holding a write lock.
+ RefPtr<CopyOnWriteValue> cowValue = mValue;
+ typename CopyOnWriteValue::AutoWriteLock lock(cowValue);
+ return aWriter(cowValue->get());
+ }
+
+ /**
+ * Write to the contained data structure using the function @aWriter.
+ * @aWriter will be passed a pointer of type |T*|. If it's currently not
+ * possible to write because a writer is currently active, @aOnError will be
+ * called instead.
+ *
+ * If readers are currently active, they will be able to continue reading from
+ * a copy of the old version of the data structure. The copy will be destroyed
+ * when all its readers finish. Later readers and writers will see the
+ * version of the data structure produced by the most recent call to Write().
+ *
+ * @return whatever value @aWriter or @aOnError returns (their return types
+ * must be consistent), or nothing if the provided functions are void.
+ */
+ template <typename WriteFunc, typename ErrorFunc>
+ auto Write(WriteFunc aWriter, ErrorFunc aOnError)
+ -> decltype(aWriter(static_cast<T*>(nullptr))) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!CanWrite()) {
+ return aOnError();
+ }
+
+ return Write(aWriter);
+ }
+
+ private:
+ CopyOnWrite(const CopyOnWrite&) = delete;
+ CopyOnWrite(CopyOnWrite&&) = delete;
+
+ RefPtr<CopyOnWriteValue> mValue;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_CopyOnWrite_h
diff --git a/image/DecodePool.cpp b/image/DecodePool.cpp
new file mode 100644
index 0000000000..753e53727c
--- /dev/null
+++ b/image/DecodePool.cpp
@@ -0,0 +1,203 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "DecodePool.h"
+
+#include <algorithm>
+
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/DebugOnly.h"
+#include "mozilla/Monitor.h"
+#include "mozilla/ProfilerLabels.h"
+#include "mozilla/SchedulerGroup.h"
+#include "mozilla/Services.h"
+#include "mozilla/StaticPrefs_image.h"
+#include "mozilla/TaskController.h"
+#include "mozilla/TimeStamp.h"
+#include "nsCOMPtr.h"
+#include "nsIObserverService.h"
+#include "nsThreadManager.h"
+#include "nsThreadUtils.h"
+#include "nsXPCOMCIDInternal.h"
+#include "prsystem.h"
+
+#include "Decoder.h"
+#include "IDecodingTask.h"
+#include "RasterImage.h"
+
+#if defined(XP_WIN)
+# include <objbase.h>
+# include "mozilla/WindowsProcessMitigations.h"
+#endif
+
+using std::max;
+using std::min;
+
+namespace mozilla {
+namespace image {
+
+///////////////////////////////////////////////////////////////////////////////
+// DecodePool implementation.
+///////////////////////////////////////////////////////////////////////////////
+
+/* static */
+StaticRefPtr<DecodePool> DecodePool::sSingleton;
+/* static */
+uint32_t DecodePool::sNumCores = 0;
+
+NS_IMPL_ISUPPORTS(DecodePool, nsIObserver)
+
+/* static */
+void DecodePool::Initialize() {
+ MOZ_ASSERT(NS_IsMainThread());
+ sNumCores = max<int32_t>(PR_GetNumberOfProcessors(), 1);
+ DecodePool::Singleton();
+}
+
+/* static */
+DecodePool* DecodePool::Singleton() {
+ if (!sSingleton) {
+ MOZ_ASSERT(NS_IsMainThread());
+ sSingleton = new DecodePool();
+ ClearOnShutdown(&sSingleton);
+ }
+
+ return sSingleton;
+}
+
+/* static */
+uint32_t DecodePool::NumberOfCores() { return sNumCores; }
+
+#if defined(XP_WIN)
+class IOThreadIniter final : public Runnable {
+ public:
+ explicit IOThreadIniter() : Runnable("image::IOThreadIniter") {}
+
+ NS_IMETHOD Run() override {
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ CoInitialize(nullptr);
+
+ return NS_OK;
+ }
+};
+#endif
+
+DecodePool::DecodePool() : mMutex("image::IOThread") {
+ // Initialize the I/O thread.
+#if defined(XP_WIN)
+ // On Windows we use the io thread to get icons from the system. Any thread
+ // that makes system calls needs to call CoInitialize. And these system calls
+ // (SHGetFileInfo) should only be called from one thread at a time, in case
+ // we ever create more than one io thread. If win32k is locked down, we can't
+ // call SHGetFileInfo anyway, so we don't need the initializer.
+ nsCOMPtr<nsIRunnable> initer =
+ IsWin32kLockedDown() ? nullptr : new IOThreadIniter();
+ nsresult rv = NS_NewNamedThread("ImageIO", getter_AddRefs(mIOThread), initer);
+#else
+ nsresult rv = NS_NewNamedThread("ImageIO", getter_AddRefs(mIOThread));
+#endif
+ MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv) && mIOThread,
+ "Should successfully create image I/O thread");
+
+ nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
+ if (obsSvc) {
+ obsSvc->AddObserver(this, "xpcom-shutdown-threads", false);
+ }
+}
+
+DecodePool::~DecodePool() {
+ MOZ_ASSERT(NS_IsMainThread(), "Must shut down DecodePool on main thread!");
+}
+
+NS_IMETHODIMP
+DecodePool::Observe(nsISupports*, const char* aTopic, const char16_t*) {
+ MOZ_ASSERT(strcmp(aTopic, "xpcom-shutdown-threads") == 0, "Unexpected topic");
+
+ mShuttingDown = true;
+
+ nsCOMPtr<nsIThread> ioThread;
+
+ {
+ MutexAutoLock lock(mMutex);
+ ioThread.swap(mIOThread);
+ }
+
+ if (ioThread) {
+ ioThread->Shutdown();
+ }
+
+ return NS_OK;
+}
+
+bool DecodePool::IsShuttingDown() const { return mShuttingDown; }
+
+class DecodingTask final : public Task {
+ public:
+ explicit DecodingTask(RefPtr<IDecodingTask>&& aTask)
+ : Task(false, aTask->Priority() == TaskPriority::eLow
+ ? EventQueuePriority::Normal
+ : EventQueuePriority::RenderBlocking),
+ mTask(aTask) {}
+
+ bool Run() override {
+ mTask->Run();
+ return true;
+ }
+
+#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
+ bool GetName(nsACString& aName) override {
+ aName.AssignLiteral("ImageDecodingTask");
+ return true;
+ }
+#endif
+
+ private:
+ RefPtr<IDecodingTask> mTask;
+};
+
+void DecodePool::AsyncRun(IDecodingTask* aTask) {
+ MOZ_ASSERT(aTask);
+
+ TaskController::Get()->AddTask(
+ MakeAndAddRef<DecodingTask>((RefPtr<IDecodingTask>(aTask))));
+}
+
+bool DecodePool::SyncRunIfPreferred(IDecodingTask* aTask,
+ const nsCString& aURI) {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(aTask);
+
+ AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING("DecodePool::SyncRunIfPreferred",
+ GRAPHICS, aURI);
+
+ if (aTask->ShouldPreferSyncRun()) {
+ aTask->Run();
+ return true;
+ }
+
+ AsyncRun(aTask);
+ return false;
+}
+
+void DecodePool::SyncRunIfPossible(IDecodingTask* aTask,
+ const nsCString& aURI) {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(aTask);
+
+ AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING("DecodePool::SyncRunIfPossible",
+ GRAPHICS, aURI);
+
+ aTask->Run();
+}
+
+already_AddRefed<nsISerialEventTarget> DecodePool::GetIOEventTarget() {
+ MutexAutoLock threadPoolLock(mMutex);
+ nsCOMPtr<nsISerialEventTarget> target = mIOThread;
+ return target.forget();
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/DecodePool.h b/image/DecodePool.h
new file mode 100644
index 0000000000..6b25aadf17
--- /dev/null
+++ b/image/DecodePool.h
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * DecodePool manages the threads used for decoding raster images.
+ */
+
+#ifndef mozilla_image_DecodePool_h
+#define mozilla_image_DecodePool_h
+
+#include "mozilla/Mutex.h"
+#include "mozilla/StaticPtr.h"
+#include "nsCOMArray.h"
+#include "nsCOMPtr.h"
+#include "nsIEventTarget.h"
+#include "nsIObserver.h"
+#include "mozilla/RefPtr.h"
+#include "nsStringFwd.h"
+
+class nsIThread;
+class nsIThreadPool;
+
+namespace mozilla {
+namespace image {
+
+class Decoder;
+class DecodePoolImpl;
+class IDecodingTask;
+
+/**
+ * DecodePool is a singleton class that manages decoding of raster images. It
+ * owns a pool of image decoding threads that are used for asynchronous
+ * decoding.
+ *
+ * DecodePool allows callers to run a decoder, handling management of the
+ * decoder's lifecycle and whether it executes on the main thread,
+ * off-main-thread in the image decoding thread pool, or on some combination of
+ * the two.
+ */
+class DecodePool final : public nsIObserver {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+
+ /// Initializes the singleton instance. Should be called from the main thread.
+ static void Initialize();
+
+ /// Returns the singleton instance.
+ static DecodePool* Singleton();
+
+ /// @return the number of processor cores we have available. This is not the
+ /// same as the number of decoding threads we're actually using.
+ static uint32_t NumberOfCores();
+
+ /// True if the DecodePool is being shutdown. This may only be called by
+ /// threads from the pool to check if they should keep working or not.
+ bool IsShuttingDown() const;
+
+ /// Ask the DecodePool to run @aTask asynchronously and return immediately.
+ void AsyncRun(IDecodingTask* aTask);
+
+ /**
+ * Run @aTask synchronously if the task would prefer it. It's up to the task
+ * itself to make this decision; @see IDecodingTask::ShouldPreferSyncRun(). If
+ * @aTask doesn't prefer it, just run @aTask asynchronously and return
+ * immediately.
+ * @return true if the task was run sync, false otherwise.
+ */
+ bool SyncRunIfPreferred(IDecodingTask* aTask, const nsCString& aURI);
+
+ /**
+ * Run @aTask synchronously. This does not guarantee that @aTask will complete
+ * synchronously. If, for example, @aTask doesn't yet have the data it needs
+ * to run synchronously, it may recover by scheduling an async task to finish
+ * up the work when the remaining data is available.
+ */
+ void SyncRunIfPossible(IDecodingTask* aTask, const nsCString& aURI);
+
+ /**
+ * Returns an event target interface to the DecodePool's I/O thread. Callers
+ * who want to deliver data to workers on the DecodePool can use this event
+ * target.
+ *
+ * @return An nsISerialEventTarget interface to the thread pool's I/O thread.
+ */
+ already_AddRefed<nsISerialEventTarget> GetIOEventTarget();
+
+ private:
+ friend class DecodePoolWorker;
+
+ DecodePool();
+ virtual ~DecodePool();
+
+ static StaticRefPtr<DecodePool> sSingleton;
+ static uint32_t sNumCores;
+ bool mShuttingDown = false;
+
+ // mMutex protects mIOThread.
+ Mutex mMutex;
+ nsCOMPtr<nsIThread> mIOThread MOZ_GUARDED_BY(mMutex);
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_DecodePool_h
diff --git a/image/DecodedSurfaceProvider.cpp b/image/DecodedSurfaceProvider.cpp
new file mode 100644
index 0000000000..cdfc27bcda
--- /dev/null
+++ b/image/DecodedSurfaceProvider.cpp
@@ -0,0 +1,234 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "DecodedSurfaceProvider.h"
+
+#include "mozilla/StaticPrefs_image.h"
+#include "mozilla/layers/SharedSurfacesChild.h"
+#include "nsProxyRelease.h"
+
+#include "Decoder.h"
+
+using namespace mozilla::gfx;
+using namespace mozilla::layers;
+
+namespace mozilla {
+namespace image {
+
+DecodedSurfaceProvider::DecodedSurfaceProvider(NotNull<RasterImage*> aImage,
+ const SurfaceKey& aSurfaceKey,
+ NotNull<Decoder*> aDecoder)
+ : ISurfaceProvider(ImageKey(aImage.get()), aSurfaceKey,
+ AvailabilityState::StartAsPlaceholder()),
+ mImage(aImage.get()),
+ mMutex("mozilla::image::DecodedSurfaceProvider"),
+ mDecoder(aDecoder.get()) {
+ MOZ_ASSERT(!mDecoder->IsMetadataDecode(),
+ "Use MetadataDecodingTask for metadata decodes");
+ MOZ_ASSERT(mDecoder->IsFirstFrameDecode(),
+ "Use AnimationSurfaceProvider for animation decodes");
+}
+
+DecodedSurfaceProvider::~DecodedSurfaceProvider() { DropImageReference(); }
+
+void DecodedSurfaceProvider::DropImageReference() {
+ if (!mImage) {
+ return; // Nothing to do.
+ }
+
+ // RasterImage objects need to be destroyed on the main thread. We also need
+ // to destroy them asynchronously, because if our surface cache entry is
+ // destroyed and we were the only thing keeping |mImage| alive, RasterImage's
+ // destructor may call into the surface cache while whatever code caused us to
+ // get evicted is holding the surface cache lock, causing deadlock.
+ RefPtr<RasterImage> image = mImage;
+ mImage = nullptr;
+ SurfaceCache::ReleaseImageOnMainThread(image.forget(),
+ /* aAlwaysProxy = */ true);
+}
+
+DrawableFrameRef DecodedSurfaceProvider::DrawableRef(size_t aFrame) {
+ MOZ_ASSERT(aFrame == 0,
+ "Requesting an animation frame from a DecodedSurfaceProvider?");
+
+ // We depend on SurfaceCache::SurfaceAvailable() to provide synchronization
+ // for methods that touch |mSurface|; after SurfaceAvailable() is called,
+ // |mSurface| should be non-null and shouldn't be mutated further until we get
+ // destroyed. That means that the assertions below are very important; we'll
+ // end up with data races if these assumptions are violated.
+ if (Availability().IsPlaceholder()) {
+ MOZ_ASSERT_UNREACHABLE("Calling DrawableRef() on a placeholder");
+ return DrawableFrameRef();
+ }
+
+ if (!mSurface) {
+ MOZ_ASSERT_UNREACHABLE("Calling DrawableRef() when we have no surface");
+ return DrawableFrameRef();
+ }
+
+ return mSurface->DrawableRef();
+}
+
+bool DecodedSurfaceProvider::IsFinished() const {
+ // See DrawableRef() for commentary on these assertions.
+ if (Availability().IsPlaceholder()) {
+ MOZ_ASSERT_UNREACHABLE("Calling IsFinished() on a placeholder");
+ return false;
+ }
+
+ if (!mSurface) {
+ MOZ_ASSERT_UNREACHABLE("Calling IsFinished() when we have no surface");
+ return false;
+ }
+
+ return mSurface->IsFinished();
+}
+
+void DecodedSurfaceProvider::SetLocked(bool aLocked) {
+ // See DrawableRef() for commentary on these assertions.
+ if (Availability().IsPlaceholder()) {
+ MOZ_ASSERT_UNREACHABLE("Calling SetLocked() on a placeholder");
+ return;
+ }
+
+ if (!mSurface) {
+ MOZ_ASSERT_UNREACHABLE("Calling SetLocked() when we have no surface");
+ return;
+ }
+
+ if (aLocked == IsLocked()) {
+ return; // Nothing to do.
+ }
+
+ // If we're locked, hold a DrawableFrameRef to |mSurface|, which will keep any
+ // volatile buffer it owns in memory.
+ mLockRef = aLocked ? mSurface->DrawableRef() : DrawableFrameRef();
+}
+
+size_t DecodedSurfaceProvider::LogicalSizeInBytes() const {
+ // Single frame images are always 32bpp.
+ IntSize size = GetSurfaceKey().Size();
+ return size_t(size.width) * size_t(size.height) * sizeof(uint32_t);
+}
+
+void DecodedSurfaceProvider::Run() {
+ MutexAutoLock lock(mMutex);
+
+ if (!mDecoder || !mImage) {
+ MOZ_ASSERT_UNREACHABLE("Running after decoding finished?");
+ return;
+ }
+
+ // Run the decoder.
+ LexerResult result = mDecoder->Decode(WrapNotNull(this));
+
+ // If there's a new surface available, announce it to the surface cache.
+ CheckForNewSurface();
+
+ if (result.is<TerminalState>()) {
+ FinishDecoding();
+ return; // We're done.
+ }
+
+ // Notify for the progress we've made so far.
+ if (mDecoder->HasProgress()) {
+ NotifyProgress(WrapNotNull(mImage), WrapNotNull(mDecoder));
+ }
+
+ MOZ_ASSERT(result.is<Yield>());
+
+ if (result == LexerResult(Yield::NEED_MORE_DATA)) {
+ // We can't make any more progress right now. The decoder itself will ensure
+ // that we get reenqueued when more data is available; just return for now.
+ return;
+ }
+
+ // Single-frame images shouldn't yield for any reason except NEED_MORE_DATA.
+ MOZ_ASSERT_UNREACHABLE("Unexpected yield for single-frame image");
+ mDecoder->TerminateFailure();
+ FinishDecoding();
+}
+
+void DecodedSurfaceProvider::CheckForNewSurface() {
+ mMutex.AssertCurrentThreadOwns();
+ MOZ_ASSERT(mDecoder);
+
+ if (mSurface) {
+ // Single-frame images should produce no more than one surface, so if we
+ // have one, it should be the same one the decoder is working on.
+ MOZ_ASSERT(mSurface.get() == mDecoder->GetCurrentFrameRef().get(),
+ "DecodedSurfaceProvider and Decoder have different surfaces?");
+ return;
+ }
+
+ // We don't have a surface yet; try to get one from the decoder.
+ mSurface = mDecoder->GetCurrentFrameRef().get();
+ if (!mSurface) {
+ return; // No surface yet.
+ }
+
+ // We just got a surface for the first time; let the surface cache know.
+ MOZ_ASSERT(mImage);
+ SurfaceCache::SurfaceAvailable(WrapNotNull(this));
+}
+
+void DecodedSurfaceProvider::FinishDecoding() {
+ mMutex.AssertCurrentThreadOwns();
+ MOZ_ASSERT(mImage);
+ MOZ_ASSERT(mDecoder);
+
+ // Send notifications.
+ NotifyDecodeComplete(WrapNotNull(mImage), WrapNotNull(mDecoder));
+
+ // If we have a new and complete surface, we can try to prune similarly sized
+ // surfaces if the cache supports it.
+ if (mSurface && mSurface->IsFinished()) {
+ SurfaceCache::PruneImage(ImageKey(mImage));
+ }
+
+ // Destroy our decoder; we don't need it anymore. (And if we don't destroy it,
+ // our surface can never be optimized, because the decoder has a
+ // RawAccessFrameRef to it.)
+ mDecoder = nullptr;
+
+ // We don't need a reference to our image anymore, either, and we don't want
+ // one. We may be stored in the surface cache for a long time after decoding
+ // finishes. If we don't drop our reference to the image, we'll end up
+ // keeping it alive as long as we remain in the surface cache, which could
+ // greatly extend the image's lifetime - in fact, if the image isn't
+ // discardable, it'd result in a leak!
+ DropImageReference();
+}
+
+bool DecodedSurfaceProvider::ShouldPreferSyncRun() const {
+ return mDecoder->ShouldSyncDecode(
+ StaticPrefs::image_mem_decode_bytes_at_a_time_AtStartup());
+}
+
+nsresult DecodedSurfaceProvider::UpdateKey(
+ layers::RenderRootStateManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources, wr::ImageKey& aKey) {
+ MOZ_ASSERT(mSurface);
+ RefPtr<SourceSurface> surface = mSurface->GetSourceSurface();
+ if (!surface) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return SharedSurfacesChild::Share(surface, aManager, aResources, aKey);
+}
+
+nsresult SimpleSurfaceProvider::UpdateKey(
+ layers::RenderRootStateManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources, wr::ImageKey& aKey) {
+ RefPtr<SourceSurface> surface = mSurface->GetSourceSurface();
+ if (!surface) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return SharedSurfacesChild::Share(surface, aManager, aResources, aKey);
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/DecodedSurfaceProvider.h b/image/DecodedSurfaceProvider.h
new file mode 100644
index 0000000000..07e722daa6
--- /dev/null
+++ b/image/DecodedSurfaceProvider.h
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * An ISurfaceProvider implemented for single-frame decoded surfaces.
+ */
+
+#ifndef mozilla_image_DecodedSurfaceProvider_h
+#define mozilla_image_DecodedSurfaceProvider_h
+
+#include "IDecodingTask.h"
+#include "ISurfaceProvider.h"
+#include "SurfaceCache.h"
+
+namespace mozilla {
+namespace image {
+
+/**
+ * An ISurfaceProvider that manages the decoding of a single-frame image and
+ * stores the resulting surface.
+ */
+class DecodedSurfaceProvider final : public ISurfaceProvider,
+ public IDecodingTask {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DecodedSurfaceProvider, override)
+
+ DecodedSurfaceProvider(NotNull<RasterImage*> aImage,
+ const SurfaceKey& aSurfaceKey,
+ NotNull<Decoder*> aDecoder);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // ISurfaceProvider implementation.
+ //////////////////////////////////////////////////////////////////////////////
+
+ public:
+ bool IsFinished() const override;
+ size_t LogicalSizeInBytes() const override;
+
+ protected:
+ DrawableFrameRef DrawableRef(size_t aFrame) override;
+ bool IsLocked() const override { return bool(mLockRef); }
+ void SetLocked(bool aLocked) override;
+
+ //////////////////////////////////////////////////////////////////////////////
+ // IDecodingTask implementation.
+ //////////////////////////////////////////////////////////////////////////////
+
+ public:
+ void Run() override;
+ bool ShouldPreferSyncRun() const override;
+
+ // Full decodes are low priority compared to metadata decodes because they
+ // don't block layout or page load.
+ TaskPriority Priority() const override { return TaskPriority::eLow; }
+
+ //////////////////////////////////////////////////////////////////////////////
+ // WebRenderImageProvider implementation.
+ //////////////////////////////////////////////////////////////////////////////
+
+ public:
+ nsresult UpdateKey(layers::RenderRootStateManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources,
+ wr::ImageKey& aKey) override;
+
+ private:
+ virtual ~DecodedSurfaceProvider();
+
+ void DropImageReference();
+ void CheckForNewSurface();
+ void FinishDecoding();
+
+ /// The image associated with our decoder. Dropped after decoding.
+ RefPtr<RasterImage> mImage;
+
+ /// Mutex protecting access to mDecoder.
+ Mutex mMutex MOZ_UNANNOTATED;
+
+ /// The decoder that will generate our surface. Dropped after decoding.
+ RefPtr<Decoder> mDecoder;
+
+ /// Our surface. Initially null until it's generated by the decoder.
+ RefPtr<imgFrame> mSurface;
+
+ /// A drawable reference to our service; used for locking.
+ DrawableFrameRef mLockRef;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_DecodedSurfaceProvider_h
diff --git a/image/Decoder.cpp b/image/Decoder.cpp
new file mode 100644
index 0000000000..76301d7596
--- /dev/null
+++ b/image/Decoder.cpp
@@ -0,0 +1,570 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "Decoder.h"
+
+#include "DecodePool.h"
+#include "IDecodingTask.h"
+#include "ISurfaceProvider.h"
+#include "gfxPlatform.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/ProfilerLabels.h"
+#include "mozilla/Telemetry.h"
+#include "nsComponentManagerUtils.h"
+#include "nsProxyRelease.h"
+#include "nsServiceManagerUtils.h"
+
+using mozilla::gfx::IntPoint;
+using mozilla::gfx::IntRect;
+using mozilla::gfx::IntSize;
+using mozilla::gfx::SurfaceFormat;
+
+namespace mozilla {
+namespace image {
+
+class MOZ_STACK_CLASS AutoRecordDecoderTelemetry final {
+ public:
+ explicit AutoRecordDecoderTelemetry(Decoder* aDecoder) : mDecoder(aDecoder) {
+ MOZ_ASSERT(mDecoder);
+
+ // Begin recording telemetry data.
+ mStartTime = TimeStamp::Now();
+ }
+
+ ~AutoRecordDecoderTelemetry() {
+ // Finish telemetry.
+ mDecoder->mDecodeTime += (TimeStamp::Now() - mStartTime);
+ }
+
+ private:
+ Decoder* mDecoder;
+ TimeStamp mStartTime;
+};
+
+Decoder::Decoder(RasterImage* aImage)
+ : mInProfile(nullptr),
+ mTransform(nullptr),
+ mImageData(nullptr),
+ mImageDataLength(0),
+ mCMSMode(gfxPlatform::GetCMSMode()),
+ mImage(aImage),
+ mFrameRecycler(nullptr),
+ mProgress(NoProgress),
+ mFrameCount(0),
+ mLoopLength(FrameTimeout::Zero()),
+ mDecoderFlags(DefaultDecoderFlags()),
+ mSurfaceFlags(DefaultSurfaceFlags()),
+ mInitialized(false),
+ mMetadataDecode(false),
+ mHaveExplicitOutputSize(false),
+ mInFrame(false),
+ mFinishedNewFrame(false),
+ mHasFrameToTake(false),
+ mReachedTerminalState(false),
+ mDecodeDone(false),
+ mError(false),
+ mShouldReportError(false),
+ mFinalizeFrames(true) {}
+
+Decoder::~Decoder() {
+ MOZ_ASSERT(mProgress == NoProgress || !mImage,
+ "Destroying Decoder without taking all its progress changes");
+ MOZ_ASSERT(mInvalidRect.IsEmpty() || !mImage,
+ "Destroying Decoder without taking all its invalidations");
+ mInitialized = false;
+
+ if (mInProfile) {
+ // mTransform belongs to us only if mInProfile is non-null
+ if (mTransform) {
+ qcms_transform_release(mTransform);
+ }
+ qcms_profile_release(mInProfile);
+ }
+
+ if (mImage && !NS_IsMainThread()) {
+ // Dispatch mImage to main thread to prevent it from being destructed by the
+ // decode thread.
+ SurfaceCache::ReleaseImageOnMainThread(mImage.forget());
+ }
+}
+
+void Decoder::SetSurfaceFlags(SurfaceFlags aSurfaceFlags) {
+ MOZ_ASSERT(!mInitialized);
+ mSurfaceFlags = aSurfaceFlags;
+ if (mSurfaceFlags & SurfaceFlags::NO_COLORSPACE_CONVERSION) {
+ mCMSMode = CMSMode::Off;
+ }
+}
+
+qcms_profile* Decoder::GetCMSOutputProfile() const {
+ if (mSurfaceFlags & SurfaceFlags::TO_SRGB_COLORSPACE) {
+ return gfxPlatform::GetCMSsRGBProfile();
+ }
+ return gfxPlatform::GetCMSOutputProfile();
+}
+
+qcms_transform* Decoder::GetCMSsRGBTransform(SurfaceFormat aFormat) const {
+ if (mSurfaceFlags & SurfaceFlags::TO_SRGB_COLORSPACE) {
+ // We want a transform to convert from sRGB to device space, but we are
+ // already using sRGB as our device space. That means we can skip
+ // color management entirely.
+ return nullptr;
+ }
+ if (qcms_profile_is_sRGB(gfxPlatform::GetCMSOutputProfile())) {
+ // Device space is sRGB so we can skip color management as well.
+ return nullptr;
+ }
+
+ switch (aFormat) {
+ case SurfaceFormat::B8G8R8A8:
+ case SurfaceFormat::B8G8R8X8:
+ return gfxPlatform::GetCMSBGRATransform();
+ case SurfaceFormat::R8G8B8A8:
+ case SurfaceFormat::R8G8B8X8:
+ return gfxPlatform::GetCMSRGBATransform();
+ case SurfaceFormat::R8G8B8:
+ return gfxPlatform::GetCMSRGBTransform();
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unsupported surface format!");
+ return nullptr;
+ }
+}
+
+/*
+ * Common implementation of the decoder interface.
+ */
+
+nsresult Decoder::Init() {
+ // No re-initializing
+ MOZ_ASSERT(!mInitialized, "Can't re-initialize a decoder!");
+
+ // All decoders must have a SourceBufferIterator.
+ MOZ_ASSERT(mIterator);
+
+ // Metadata decoders must not set an output size.
+ MOZ_ASSERT_IF(mMetadataDecode, !mHaveExplicitOutputSize);
+
+ // All decoders must be anonymous except for metadata decoders.
+ // XXX(seth): Soon that exception will be removed.
+ MOZ_ASSERT_IF(mImage, IsMetadataDecode());
+
+ // Implementation-specific initialization.
+ nsresult rv = InitInternal();
+
+ mInitialized = true;
+
+ return rv;
+}
+
+LexerResult Decoder::Decode(IResumable* aOnResume /* = nullptr */) {
+ MOZ_ASSERT(mInitialized, "Should be initialized here");
+ MOZ_ASSERT(mIterator, "Should have a SourceBufferIterator");
+
+ // If we're already done, don't attempt to keep decoding.
+ if (GetDecodeDone()) {
+ return LexerResult(HasError() ? TerminalState::FAILURE
+ : TerminalState::SUCCESS);
+ }
+
+ LexerResult lexerResult(TerminalState::FAILURE);
+ {
+ AUTO_PROFILER_LABEL_CATEGORY_PAIR_RELEVANT_FOR_JS(GRAPHICS_ImageDecoding);
+ AutoRecordDecoderTelemetry telemetry(this);
+
+ lexerResult = DoDecode(*mIterator, aOnResume);
+ };
+
+ if (lexerResult.is<Yield>()) {
+ // We either need more data to continue (in which case either @aOnResume or
+ // the caller will reschedule us to run again later), or the decoder is
+ // yielding to allow the caller access to some intermediate output.
+ return lexerResult;
+ }
+
+ // We reached a terminal state; we're now done decoding.
+ MOZ_ASSERT(lexerResult.is<TerminalState>());
+ mReachedTerminalState = true;
+
+ // If decoding failed, record that fact.
+ if (lexerResult.as<TerminalState>() == TerminalState::FAILURE) {
+ PostError();
+ }
+
+ // Perform final cleanup.
+ CompleteDecode();
+
+ return LexerResult(HasError() ? TerminalState::FAILURE
+ : TerminalState::SUCCESS);
+}
+
+LexerResult Decoder::TerminateFailure() {
+ PostError();
+
+ // Perform final cleanup if need be.
+ if (!mReachedTerminalState) {
+ mReachedTerminalState = true;
+ CompleteDecode();
+ }
+
+ return LexerResult(TerminalState::FAILURE);
+}
+
+bool Decoder::ShouldSyncDecode(size_t aByteLimit) {
+ MOZ_ASSERT(aByteLimit > 0);
+ MOZ_ASSERT(mIterator, "Should have a SourceBufferIterator");
+
+ return mIterator->RemainingBytesIsNoMoreThan(aByteLimit);
+}
+
+void Decoder::CompleteDecode() {
+ // Implementation-specific finalization.
+ nsresult rv = BeforeFinishInternal();
+ if (NS_FAILED(rv)) {
+ PostError();
+ }
+
+ rv = HasError() ? FinishWithErrorInternal() : FinishInternal();
+ if (NS_FAILED(rv)) {
+ PostError();
+ }
+
+ if (IsMetadataDecode()) {
+ // If this was a metadata decode and we never got a size, the decode failed.
+ if (!HasSize()) {
+ PostError();
+ }
+ return;
+ }
+
+ // If the implementation left us mid-frame, finish that up. Note that it may
+ // have left us transparent.
+ if (mInFrame) {
+ PostHasTransparency();
+ PostFrameStop();
+ }
+
+ // If PostDecodeDone() has not been called, we may need to send teardown
+ // notifications if it is unrecoverable.
+ if (mDecodeDone) {
+ MOZ_ASSERT(HasError() || mCurrentFrame, "Should have an error or a frame");
+ } else {
+ // We should always report an error to the console in this case.
+ mShouldReportError = true;
+
+ if (GetCompleteFrameCount() > 0) {
+ // We're usable if we have at least one complete frame, so do exactly
+ // what we should have when the decoder completed.
+ PostHasTransparency();
+ PostDecodeDone();
+ } else {
+ // We're not usable. Record some final progress indicating the error.
+ mProgress |= FLAG_DECODE_COMPLETE | FLAG_HAS_ERROR;
+ }
+ }
+}
+
+void Decoder::SetOutputSize(const OrientedIntSize& aSize) {
+ mOutputSize = Some(aSize);
+ mHaveExplicitOutputSize = true;
+}
+
+Maybe<OrientedIntSize> Decoder::ExplicitOutputSize() const {
+ MOZ_ASSERT_IF(mHaveExplicitOutputSize, mOutputSize);
+ return mHaveExplicitOutputSize ? mOutputSize : Nothing();
+}
+
+Maybe<uint32_t> Decoder::TakeCompleteFrameCount() {
+ const bool finishedNewFrame = mFinishedNewFrame;
+ mFinishedNewFrame = false;
+ return finishedNewFrame ? Some(GetCompleteFrameCount()) : Nothing();
+}
+
+DecoderFinalStatus Decoder::FinalStatus() const {
+ return DecoderFinalStatus(IsMetadataDecode(), GetDecodeDone(), HasError(),
+ ShouldReportError());
+}
+
+DecoderTelemetry Decoder::Telemetry() const {
+ MOZ_ASSERT(mIterator);
+ return DecoderTelemetry(SpeedHistogram(),
+ mIterator ? mIterator->ByteCount() : 0,
+ mIterator ? mIterator->ChunkCount() : 0, mDecodeTime);
+}
+
+nsresult Decoder::AllocateFrame(const gfx::IntSize& aOutputSize,
+ gfx::SurfaceFormat aFormat,
+ const Maybe<AnimationParams>& aAnimParams) {
+ mCurrentFrame = AllocateFrameInternal(aOutputSize, aFormat, aAnimParams,
+ std::move(mCurrentFrame));
+
+ if (mCurrentFrame) {
+ mHasFrameToTake = true;
+
+ // Gather the raw pointers the decoders will use.
+ mCurrentFrame->GetImageData(&mImageData, &mImageDataLength);
+
+ // We should now be on |aFrameNum|. (Note that we're comparing the frame
+ // number, which is zero-based, with the frame count, which is one-based.)
+ MOZ_ASSERT_IF(aAnimParams, aAnimParams->mFrameNum + 1 == mFrameCount);
+
+ // If we're past the first frame, PostIsAnimated() should've been called.
+ MOZ_ASSERT_IF(mFrameCount > 1, HasAnimation());
+
+ // Update our state to reflect the new frame.
+ MOZ_ASSERT(!mInFrame, "Starting new frame but not done with old one!");
+ mInFrame = true;
+ }
+
+ return mCurrentFrame ? NS_OK : NS_ERROR_FAILURE;
+}
+
+RawAccessFrameRef Decoder::AllocateFrameInternal(
+ const gfx::IntSize& aOutputSize, SurfaceFormat aFormat,
+ const Maybe<AnimationParams>& aAnimParams,
+ RawAccessFrameRef&& aPreviousFrame) {
+ if (HasError()) {
+ return RawAccessFrameRef();
+ }
+
+ uint32_t frameNum = aAnimParams ? aAnimParams->mFrameNum : 0;
+ if (frameNum != mFrameCount) {
+ MOZ_ASSERT_UNREACHABLE("Allocating frames out of order");
+ return RawAccessFrameRef();
+ }
+
+ if (aOutputSize.width <= 0 || aOutputSize.height <= 0) {
+ NS_WARNING("Trying to add frame with zero or negative size");
+ return RawAccessFrameRef();
+ }
+
+ if (frameNum > 0) {
+ if (aPreviousFrame->GetDisposalMethod() !=
+ DisposalMethod::RESTORE_PREVIOUS) {
+ // If the new restore frame is the direct previous frame, then we know
+ // the dirty rect is composed only of the current frame's blend rect and
+ // the restore frame's clear rect (if applicable) which are handled in
+ // filters.
+ mRestoreFrame = std::move(aPreviousFrame);
+ mRestoreDirtyRect.SetBox(0, 0, 0, 0);
+ } else {
+ // We only need the previous frame's dirty rect, because while there may
+ // have been several frames between us and mRestoreFrame, the only areas
+ // that changed are the restore frame's clear rect, the current frame
+ // blending rect, and the previous frame's blending rect. All else is
+ // forgotten due to us restoring the same frame again.
+ mRestoreDirtyRect = aPreviousFrame->GetBoundedBlendRect();
+ }
+ }
+
+ RawAccessFrameRef ref;
+
+ // If we have a frame recycler, it must be for an animated image producing
+ // full frames. If the higher layers are discarding frames because of the
+ // memory footprint, then the recycler will allow us to reuse the buffers.
+ // Each frame should be the same size and have mostly the same properties.
+ if (mFrameRecycler) {
+ MOZ_ASSERT(aAnimParams);
+
+ ref = mFrameRecycler->RecycleFrame(mRecycleRect);
+ if (ref) {
+ // If the recycled frame is actually the current restore frame, we cannot
+ // use it. If the next restore frame is the new frame we are creating, in
+ // theory we could reuse it, but we would need to store the restore frame
+ // animation parameters elsewhere. For now we just drop it.
+ bool blocked = ref.get() == mRestoreFrame.get();
+ if (!blocked) {
+ blocked = NS_FAILED(ref->InitForDecoderRecycle(aAnimParams.ref()));
+ }
+
+ if (blocked) {
+ ref.reset();
+ }
+ }
+ }
+
+ // Either the recycler had nothing to give us, or we don't have a recycler.
+ // Produce a new frame to store the data.
+ if (!ref) {
+ // There is no underlying data to reuse, so reset the recycle rect to be
+ // the full frame, to ensure the restore frame is fully copied.
+ mRecycleRect = IntRect(IntPoint(0, 0), aOutputSize);
+
+ bool nonPremult = bool(mSurfaceFlags & SurfaceFlags::NO_PREMULTIPLY_ALPHA);
+ auto frame = MakeNotNull<RefPtr<imgFrame>>();
+ if (NS_FAILED(frame->InitForDecoder(aOutputSize, aFormat, nonPremult,
+ aAnimParams, bool(mFrameRecycler)))) {
+ NS_WARNING("imgFrame::Init should succeed");
+ return RawAccessFrameRef();
+ }
+
+ ref = frame->RawAccessRef();
+ if (!ref) {
+ frame->Abort();
+ return RawAccessFrameRef();
+ }
+ }
+
+ mFrameCount++;
+
+ return ref;
+}
+
+/*
+ * Hook stubs. Override these as necessary in decoder implementations.
+ */
+
+nsresult Decoder::InitInternal() { return NS_OK; }
+nsresult Decoder::BeforeFinishInternal() { return NS_OK; }
+nsresult Decoder::FinishInternal() { return NS_OK; }
+
+nsresult Decoder::FinishWithErrorInternal() {
+ MOZ_ASSERT(!mInFrame);
+ return NS_OK;
+}
+
+/*
+ * Progress Notifications
+ */
+
+void Decoder::PostSize(int32_t aWidth, int32_t aHeight,
+ Orientation aOrientation, Resolution aResolution) {
+ // Validate.
+ MOZ_ASSERT(aWidth >= 0, "Width can't be negative!");
+ MOZ_ASSERT(aHeight >= 0, "Height can't be negative!");
+
+ // Set our intrinsic size.
+ mImageMetadata.SetSize(aWidth, aHeight, aOrientation, aResolution);
+
+ // Verify it is the expected size, if given. Note that this is only used by
+ // the ICO decoder for embedded image types, so only its subdecoders are
+ // required to handle failures in PostSize.
+ if (!IsExpectedSize()) {
+ PostError();
+ return;
+ }
+
+ // Set our output size if it's not already set.
+ if (!mOutputSize) {
+ mOutputSize = Some(mImageMetadata.GetSize());
+ }
+
+ MOZ_ASSERT(mOutputSize->width <= mImageMetadata.GetSize().width &&
+ mOutputSize->height <= mImageMetadata.GetSize().height,
+ "Output size will result in upscaling");
+
+ // Record this notification.
+ mProgress |= FLAG_SIZE_AVAILABLE;
+}
+
+void Decoder::PostHasTransparency() { mProgress |= FLAG_HAS_TRANSPARENCY; }
+
+void Decoder::PostIsAnimated(FrameTimeout aFirstFrameTimeout) {
+ mProgress |= FLAG_IS_ANIMATED;
+ mImageMetadata.SetHasAnimation();
+ mImageMetadata.SetFirstFrameTimeout(aFirstFrameTimeout);
+}
+
+void Decoder::PostFrameStop(Opacity aFrameOpacity) {
+ // We should be mid-frame
+ MOZ_ASSERT(!IsMetadataDecode(), "Stopping frame during metadata decode");
+ MOZ_ASSERT(mInFrame, "Stopping frame when we didn't start one");
+ MOZ_ASSERT(mCurrentFrame, "Stopping frame when we don't have one");
+
+ // Update our state.
+ mInFrame = false;
+ mFinishedNewFrame = true;
+
+ mCurrentFrame->Finish(
+ aFrameOpacity, mFinalizeFrames,
+ /* aOrientationSwapsWidthAndHeight = */ mImageMetadata.HasOrientation() &&
+ mImageMetadata.GetOrientation().SwapsWidthAndHeight());
+
+ mProgress |= FLAG_FRAME_COMPLETE;
+
+ mLoopLength += mCurrentFrame->GetTimeout();
+
+ if (mFrameCount == 1) {
+ // If we're not sending partial invalidations, then we send an invalidation
+ // here when the first frame is complete.
+ if (!ShouldSendPartialInvalidations()) {
+ mInvalidRect.UnionRect(mInvalidRect,
+ OrientedIntRect(OrientedIntPoint(), Size()));
+ }
+
+ // If we dispose of the first frame by clearing it, then the first frame's
+ // refresh area is all of itself. RESTORE_PREVIOUS is invalid (assumed to
+ // be DISPOSE_CLEAR).
+ switch (mCurrentFrame->GetDisposalMethod()) {
+ default:
+ MOZ_FALLTHROUGH_ASSERT("Unexpected DisposalMethod");
+ case DisposalMethod::CLEAR:
+ case DisposalMethod::CLEAR_ALL:
+ case DisposalMethod::RESTORE_PREVIOUS:
+ mFirstFrameRefreshArea = IntRect(IntPoint(), Size().ToUnknownSize());
+ break;
+ case DisposalMethod::KEEP:
+ case DisposalMethod::NOT_SPECIFIED:
+ break;
+ }
+ } else {
+ // Some GIFs are huge but only have a small area that they animate. We only
+ // need to refresh that small area when frame 0 comes around again.
+ mFirstFrameRefreshArea.UnionRect(mFirstFrameRefreshArea,
+ mCurrentFrame->GetBoundedBlendRect());
+ }
+}
+
+void Decoder::PostInvalidation(const OrientedIntRect& aRect,
+ const Maybe<OrientedIntRect>& aRectAtOutputSize
+ /* = Nothing() */) {
+ // We should be mid-frame
+ MOZ_ASSERT(mInFrame, "Can't invalidate when not mid-frame!");
+ MOZ_ASSERT(mCurrentFrame, "Can't invalidate when not mid-frame!");
+
+ // Record this invalidation, unless we're not sending partial invalidations
+ // or we're past the first frame.
+ if (ShouldSendPartialInvalidations() && mFrameCount == 1) {
+ mInvalidRect.UnionRect(mInvalidRect, aRect);
+ mCurrentFrame->ImageUpdated(
+ aRectAtOutputSize.valueOr(aRect).ToUnknownRect());
+ }
+}
+
+void Decoder::PostDecodeDone(int32_t aLoopCount /* = 0 */) {
+ MOZ_ASSERT(!IsMetadataDecode(), "Done with decoding in metadata decode");
+ MOZ_ASSERT(!mInFrame, "Can't be done decoding if we're mid-frame!");
+ MOZ_ASSERT(!mDecodeDone, "Decode already done!");
+ mDecodeDone = true;
+
+ mImageMetadata.SetLoopCount(aLoopCount);
+
+ // Some metadata that we track should take into account every frame in the
+ // image. If this is a first-frame-only decode, our accumulated loop length
+ // and first frame refresh area only includes the first frame, so it's not
+ // correct and we don't record it.
+ if (!IsFirstFrameDecode()) {
+ mImageMetadata.SetLoopLength(mLoopLength);
+ mImageMetadata.SetFirstFrameRefreshArea(mFirstFrameRefreshArea);
+ }
+
+ mProgress |= FLAG_DECODE_COMPLETE;
+}
+
+void Decoder::PostError() {
+ mError = true;
+
+ if (mInFrame) {
+ MOZ_ASSERT(mCurrentFrame);
+ MOZ_ASSERT(mFrameCount > 0);
+ mCurrentFrame->Abort();
+ mInFrame = false;
+ --mFrameCount;
+ mHasFrameToTake = false;
+ }
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/Decoder.h b/image/Decoder.h
new file mode 100644
index 0000000000..afb1236880
--- /dev/null
+++ b/image/Decoder.h
@@ -0,0 +1,641 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_Decoder_h
+#define mozilla_image_Decoder_h
+
+#include "FrameAnimator.h"
+#include "RasterImage.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/NotNull.h"
+#include "mozilla/RefPtr.h"
+#include "AnimationParams.h"
+#include "DecoderFlags.h"
+#include "ImageMetadata.h"
+#include "Orientation.h"
+#include "Resolution.h"
+#include "SourceBuffer.h"
+#include "StreamingLexer.h"
+#include "SurfaceFlags.h"
+#include "qcms.h"
+
+enum class CMSMode : int32_t;
+
+namespace mozilla {
+
+namespace Telemetry {
+enum HistogramID : uint32_t;
+} // namespace Telemetry
+
+namespace image {
+
+class imgFrame;
+
+struct DecoderFinalStatus final {
+ DecoderFinalStatus(bool aWasMetadataDecode, bool aFinished, bool aHadError,
+ bool aShouldReportError)
+ : mWasMetadataDecode(aWasMetadataDecode),
+ mFinished(aFinished),
+ mHadError(aHadError),
+ mShouldReportError(aShouldReportError) {}
+
+ /// True if this was a metadata decode.
+ const bool mWasMetadataDecode : 1;
+
+ /// True if this decoder finished, whether successfully or due to failure.
+ const bool mFinished : 1;
+
+ /// True if this decoder encountered an error.
+ const bool mHadError : 1;
+
+ /// True if this decoder encountered the kind of error that should be reported
+ /// to the console.
+ const bool mShouldReportError : 1;
+};
+
+struct DecoderTelemetry final {
+ DecoderTelemetry(const Maybe<Telemetry::HistogramID>& aSpeedHistogram,
+ size_t aBytesDecoded, uint32_t aChunkCount,
+ TimeDuration aDecodeTime)
+ : mSpeedHistogram(aSpeedHistogram),
+ mBytesDecoded(aBytesDecoded),
+ mChunkCount(aChunkCount),
+ mDecodeTime(aDecodeTime) {}
+
+ /// @return our decoder's speed, in KBps.
+ int32_t Speed() const {
+ return mBytesDecoded / (1024 * mDecodeTime.ToSeconds());
+ }
+
+ /// @return our decoder's decode time, in microseconds.
+ int32_t DecodeTimeMicros() { return mDecodeTime.ToMicroseconds(); }
+
+ /// The per-image-format telemetry ID for recording our decoder's speed, or
+ /// Nothing() if we don't record speed telemetry for this kind of decoder.
+ const Maybe<Telemetry::HistogramID> mSpeedHistogram;
+
+ /// The number of bytes of input our decoder processed.
+ const size_t mBytesDecoded;
+
+ /// The number of chunks our decoder's input was divided into.
+ const uint32_t mChunkCount;
+
+ /// The amount of time our decoder spent inside DoDecode().
+ const TimeDuration mDecodeTime;
+};
+
+/**
+ * Interface which owners of an animated Decoder object must implement in order
+ * to use recycling. It allows the decoder to get a handle to the recycled
+ * frames.
+ */
+class IDecoderFrameRecycler {
+ public:
+ /**
+ * Request the next available recycled imgFrame from the recycler.
+ *
+ * @param aRecycleRect If a frame is returned, this must be set to the
+ * accumulated dirty rect between the frame being
+ * recycled, and the frame being generated.
+ *
+ * @returns The recycled frame, if any is available.
+ */
+ virtual RawAccessFrameRef RecycleFrame(gfx::IntRect& aRecycleRect) = 0;
+};
+
+class Decoder {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Decoder)
+
+ explicit Decoder(RasterImage* aImage);
+
+ /**
+ * Initialize an image decoder. Decoders may not be re-initialized.
+ *
+ * @return NS_OK if the decoder could be initialized successfully.
+ */
+ nsresult Init();
+
+ /**
+ * Decodes, reading all data currently available in the SourceBuffer.
+ *
+ * If more data is needed and @aOnResume is non-null, Decode() will schedule
+ * @aOnResume to be called when more data is available.
+ *
+ * @return a LexerResult which may indicate:
+ * - the image has been successfully decoded (TerminalState::SUCCESS), or
+ * - the image has failed to decode (TerminalState::FAILURE), or
+ * - the decoder is yielding until it gets more data
+ * (Yield::NEED_MORE_DATA), or
+ * - the decoder is yielding to allow the caller to access intermediate
+ * output (Yield::OUTPUT_AVAILABLE).
+ */
+ LexerResult Decode(IResumable* aOnResume = nullptr);
+
+ /**
+ * Terminate this decoder in a failure state, just as if the decoder
+ * implementation had returned TerminalState::FAILURE from DoDecode().
+ *
+ * XXX(seth): This method should be removed ASAP; it exists only because
+ * RasterImage::FinalizeDecoder() requires an actual Decoder object as an
+ * argument, so we can't simply tell RasterImage a decode failed except via an
+ * intervening decoder. We'll fix this in bug 1291071.
+ */
+ LexerResult TerminateFailure();
+
+ /**
+ * Given a maximum number of bytes we're willing to decode, @aByteLimit,
+ * returns true if we should attempt to run this decoder synchronously.
+ */
+ bool ShouldSyncDecode(size_t aByteLimit);
+
+ /**
+ * Gets the invalidation region accumulated by the decoder so far, and clears
+ * the decoder's invalidation region. This means that each call to
+ * TakeInvalidRect() returns only the invalidation region accumulated since
+ * the last call to TakeInvalidRect().
+ */
+ OrientedIntRect TakeInvalidRect() {
+ OrientedIntRect invalidRect = mInvalidRect;
+ mInvalidRect.SetEmpty();
+ return invalidRect;
+ }
+
+ /**
+ * Gets the progress changes accumulated by the decoder so far, and clears
+ * them. This means that each call to TakeProgress() returns only the changes
+ * accumulated since the last call to TakeProgress().
+ */
+ Progress TakeProgress() {
+ Progress progress = mProgress;
+ mProgress = NoProgress;
+ return progress;
+ }
+
+ /**
+ * Returns true if there's any progress to report.
+ */
+ bool HasProgress() const {
+ return mProgress != NoProgress || !mInvalidRect.IsEmpty() ||
+ mFinishedNewFrame;
+ }
+
+ /*
+ * State.
+ */
+
+ /**
+ * If we're doing a metadata decode, we only decode the image's headers, which
+ * is enough to determine the image's intrinsic size. A metadata decode is
+ * enabled by calling SetMetadataDecode() *before* calling Init().
+ */
+ void SetMetadataDecode(bool aMetadataDecode) {
+ MOZ_ASSERT(!mInitialized, "Shouldn't be initialized yet");
+ mMetadataDecode = aMetadataDecode;
+ }
+ bool IsMetadataDecode() const { return mMetadataDecode; }
+
+ /**
+ * Sets the output size of this decoder. If this is smaller than the intrinsic
+ * size of the image, we'll downscale it while decoding. For memory usage
+ * reasons, upscaling is forbidden and will trigger assertions in debug
+ * builds.
+ *
+ * Not calling SetOutputSize() means that we should just decode at the
+ * intrinsic size, whatever it is.
+ *
+ * If SetOutputSize() was called, ExplicitOutputSize() can be used to
+ * determine the value that was passed to it.
+ *
+ * This must be called before Init() is called.
+ */
+ void SetOutputSize(const OrientedIntSize& aSize);
+
+ /**
+ * @return the output size of this decoder. If this is smaller than the
+ * intrinsic size, then the image will be downscaled during the decoding
+ * process.
+ *
+ * Illegal to call if HasSize() returns false.
+ */
+ OrientedIntSize OutputSize() const {
+ MOZ_ASSERT(HasSize());
+ return *mOutputSize;
+ }
+
+ /**
+ * @return either the size passed to SetOutputSize() or Nothing(), indicating
+ * that SetOutputSize() was not explicitly called.
+ */
+ Maybe<OrientedIntSize> ExplicitOutputSize() const;
+
+ /**
+ * Sets the expected image size of this decoder. Decoding will fail if this
+ * does not match.
+ */
+ void SetExpectedSize(const OrientedIntSize& aSize) {
+ mExpectedSize.emplace(aSize);
+ }
+
+ /**
+ * Is the image size what was expected, if specified?
+ */
+ bool IsExpectedSize() const {
+ return mExpectedSize.isNothing() || *mExpectedSize == Size();
+ }
+
+ /**
+ * Set an iterator to the SourceBuffer which will feed data to this decoder.
+ * This must always be called before calling Init(). (And only before Init().)
+ *
+ * XXX(seth): We should eliminate this method and pass a SourceBufferIterator
+ * to the various decoder constructors instead.
+ */
+ void SetIterator(SourceBufferIterator&& aIterator) {
+ MOZ_ASSERT(!mInitialized, "Shouldn't be initialized yet");
+ mIterator.emplace(std::move(aIterator));
+ }
+
+ SourceBuffer* GetSourceBuffer() const { return mIterator->Owner(); }
+
+ /**
+ * Should this decoder send partial invalidations?
+ */
+ bool ShouldSendPartialInvalidations() const {
+ return !(mDecoderFlags & DecoderFlags::IS_REDECODE);
+ }
+
+ /**
+ * Should we stop decoding after the first frame?
+ */
+ bool IsFirstFrameDecode() const {
+ return bool(mDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY);
+ }
+
+ /**
+ * @return the number of complete animation frames which have been decoded so
+ * far, if it has changed since the last call to TakeCompleteFrameCount();
+ * otherwise, returns Nothing().
+ */
+ Maybe<uint32_t> TakeCompleteFrameCount();
+
+ // The number of frames we have, including anything in-progress. Thus, this
+ // is only 0 if we haven't begun any frames.
+ uint32_t GetFrameCount() { return mFrameCount; }
+
+ // Did we discover that the image we're decoding is animated?
+ bool HasAnimation() const { return mImageMetadata.HasAnimation(); }
+
+ // Error tracking
+ bool HasError() const { return mError; }
+ bool ShouldReportError() const { return mShouldReportError; }
+
+ // Finalize frames
+ void SetFinalizeFrames(bool aFinalize) { mFinalizeFrames = aFinalize; }
+ bool GetFinalizeFrames() const { return mFinalizeFrames; }
+
+ /// Did we finish decoding enough that calling Decode() again would be
+ /// useless?
+ bool GetDecodeDone() const {
+ return mReachedTerminalState || mDecodeDone ||
+ (mMetadataDecode && HasSize()) || HasError();
+ }
+
+ /// Are we in the middle of a frame right now? Used for assertions only.
+ bool InFrame() const { return mInFrame; }
+
+ /// Is the image valid if embedded inside an ICO.
+ virtual bool IsValidICOResource() const { return false; }
+
+ /// Type of decoder.
+ virtual DecoderType GetType() const { return DecoderType::UNKNOWN; }
+
+ enum DecodeStyle {
+ PROGRESSIVE, // produce intermediate frames representing the partial
+ // state of the image
+ SEQUENTIAL // decode to final image immediately
+ };
+
+ /**
+ * Get or set the DecoderFlags that influence the behavior of this decoder.
+ */
+ void SetDecoderFlags(DecoderFlags aDecoderFlags) {
+ MOZ_ASSERT(!mInitialized);
+ mDecoderFlags = aDecoderFlags;
+ }
+ DecoderFlags GetDecoderFlags() const { return mDecoderFlags; }
+
+ /**
+ * Get or set the SurfaceFlags that select the kind of output this decoder
+ * will produce.
+ */
+ void SetSurfaceFlags(SurfaceFlags aSurfaceFlags);
+ SurfaceFlags GetSurfaceFlags() const { return mSurfaceFlags; }
+
+ /// @return true if we know the intrinsic size of the image we're decoding.
+ bool HasSize() const { return mImageMetadata.HasSize(); }
+
+ /**
+ * @return the intrinsic size of the image we're decoding.
+ *
+ * Illegal to call if HasSize() returns false.
+ */
+ OrientedIntSize Size() const {
+ MOZ_ASSERT(HasSize());
+ return mImageMetadata.GetSize();
+ }
+
+ /**
+ * @return an IntRect which covers the entire area of this image at its
+ * intrinsic size, appropriate for use as a frame rect when the image itself
+ * does not specify one.
+ *
+ * Illegal to call if HasSize() returns false.
+ */
+ OrientedIntRect FullFrame() const {
+ return OrientedIntRect(OrientedIntPoint(), Size());
+ }
+
+ /**
+ * @return an IntRect which covers the entire area of this image at its size
+ * after scaling - that is, at its output size.
+ *
+ * XXX(seth): This is only used for decoders which are using the old
+ * Downscaler code instead of SurfacePipe, since the old AllocateFrame() and
+ * Downscaler APIs required that the frame rect be specified in output space.
+ * We should remove this once all decoders use SurfacePipe.
+ *
+ * Illegal to call if HasSize() returns false.
+ */
+ OrientedIntRect FullOutputFrame() const {
+ return OrientedIntRect(OrientedIntPoint(), OutputSize());
+ }
+
+ /**
+ * @return the orientation of the image.
+ *
+ * Illegal to call if HasSize() returns false.
+ */
+ Orientation GetOrientation() const {
+ MOZ_ASSERT(HasSize());
+ return mImageMetadata.GetOrientation();
+ }
+
+ /// @return final status information about this decoder. Should be called
+ /// after we decide we're not going to run the decoder anymore.
+ DecoderFinalStatus FinalStatus() const;
+
+ /// @return the metadata we collected about this image while decoding.
+ const ImageMetadata& GetImageMetadata() { return mImageMetadata; }
+
+ /// @return performance telemetry we collected while decoding.
+ DecoderTelemetry Telemetry() const;
+
+ /**
+ * @return a weak pointer to the image associated with this decoder. Illegal
+ * to call if this decoder is not associated with an image.
+ */
+ NotNull<RasterImage*> GetImage() const { return WrapNotNull(mImage.get()); }
+
+ /**
+ * @return a possibly-null weak pointer to the image associated with this
+ * decoder. May be called even if this decoder is not associated with an
+ * image.
+ */
+ RasterImage* GetImageMaybeNull() const { return mImage.get(); }
+
+ RawAccessFrameRef GetCurrentFrameRef() {
+ return mCurrentFrame ? mCurrentFrame->RawAccessRef() : RawAccessFrameRef();
+ }
+
+ /**
+ * For use during decoding only. Allows the BlendAnimationFilter to get the
+ * current frame we are producing for its animation parameters.
+ */
+ imgFrame* GetCurrentFrame() { return mCurrentFrame.get(); }
+
+ /**
+ * For use during decoding only. Allows the BlendAnimationFilter to get the
+ * frame it should be pulling the previous frame data from.
+ */
+ const RawAccessFrameRef& GetRestoreFrameRef() const { return mRestoreFrame; }
+
+ const gfx::IntRect& GetRestoreDirtyRect() const { return mRestoreDirtyRect; }
+
+ const gfx::IntRect& GetRecycleRect() const { return mRecycleRect; }
+
+ const gfx::IntRect& GetFirstFrameRefreshArea() const {
+ return mFirstFrameRefreshArea;
+ }
+
+ bool HasFrameToTake() const { return mHasFrameToTake; }
+ void ClearHasFrameToTake() {
+ MOZ_ASSERT(mHasFrameToTake);
+ mHasFrameToTake = false;
+ }
+
+ IDecoderFrameRecycler* GetFrameRecycler() const { return mFrameRecycler; }
+ void SetFrameRecycler(IDecoderFrameRecycler* aFrameRecycler) {
+ mFrameRecycler = aFrameRecycler;
+ }
+
+ protected:
+ friend class AutoRecordDecoderTelemetry;
+ friend class DecoderTestHelper;
+ friend class nsBMPDecoder;
+ friend class nsICODecoder;
+ friend class ReorientSurfaceSink;
+ friend class SurfaceSink;
+
+ virtual ~Decoder();
+
+ /*
+ * Internal hooks. Decoder implementations may override these and
+ * only these methods.
+ *
+ * BeforeFinishInternal() can be used to detect if decoding is in an
+ * incomplete state, e.g. due to file truncation, in which case it should
+ * return a failing nsresult.
+ */
+ virtual nsresult InitInternal();
+ virtual LexerResult DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) = 0;
+ virtual nsresult BeforeFinishInternal();
+ virtual nsresult FinishInternal();
+ virtual nsresult FinishWithErrorInternal();
+
+ qcms_profile* GetCMSOutputProfile() const;
+ qcms_transform* GetCMSsRGBTransform(gfx::SurfaceFormat aFormat) const;
+
+ /**
+ * @return the per-image-format telemetry ID for recording this decoder's
+ * speed, or Nothing() if we don't record speed telemetry for this kind of
+ * decoder.
+ */
+ virtual Maybe<Telemetry::HistogramID> SpeedHistogram() const {
+ return Nothing();
+ }
+
+ /*
+ * Progress notifications.
+ */
+
+ // Called by decoders when they determine the size of the image. Informs
+ // the image of its size and sends notifications.
+ void PostSize(int32_t aWidth, int32_t aHeight, Orientation = Orientation(),
+ Resolution = Resolution());
+
+ // Called by decoders if they determine that the image has transparency.
+ //
+ // This should be fired as early as possible to allow observers to do things
+ // that affect content, so it's necessarily pessimistic - if there's a
+ // possibility that the image has transparency, for example because its header
+ // specifies that it has an alpha channel, we fire PostHasTransparency
+ // immediately. PostFrameStop's aFrameOpacity argument, on the other hand, is
+ // only used internally to ImageLib. Because PostFrameStop isn't delivered
+ // until the entire frame has been decoded, decoders may take into account the
+ // actual contents of the frame and give a more accurate result.
+ void PostHasTransparency();
+
+ // Called by decoders if they determine that the image is animated.
+ //
+ // @param aTimeout The time for which the first frame should be shown before
+ // we advance to the next frame.
+ void PostIsAnimated(FrameTimeout aFirstFrameTimeout);
+
+ // Called by decoders when they end a frame. Informs the image, sends
+ // notifications, and does internal book-keeping.
+ // Specify whether this frame is opaque as an optimization.
+ // For animated images, specify the disposal, blend method and timeout for
+ // this frame.
+ void PostFrameStop(Opacity aFrameOpacity = Opacity::SOME_TRANSPARENCY);
+
+ /**
+ * Called by the decoders when they have a region to invalidate. We may not
+ * actually pass these invalidations on right away.
+ *
+ * @param aRect The invalidation rect in the coordinate system of the unscaled
+ * image (that is, the image at its intrinsic size).
+ * @param aRectAtOutputSize If not Nothing(), the invalidation rect in the
+ * coordinate system of the scaled image (that is,
+ * the image at our output size). This must
+ * be supplied if we're downscaling during decode.
+ */
+ void PostInvalidation(
+ const OrientedIntRect& aRect,
+ const Maybe<OrientedIntRect>& aRectAtOutputSize = Nothing());
+
+ // Called by the decoders when they have successfully decoded the image. This
+ // may occur as the result of the decoder getting to the appropriate point in
+ // the stream, or by us calling FinishInternal().
+ //
+ // May not be called mid-frame.
+ //
+ // For animated images, specify the loop count. -1 means loop forever, 0
+ // means a single iteration, stopping on the last frame.
+ void PostDecodeDone(int32_t aLoopCount = 0);
+
+ /**
+ * Allocates a new frame, making it our current frame if successful.
+ */
+ nsresult AllocateFrame(const gfx::IntSize& aOutputSize,
+ gfx::SurfaceFormat aFormat,
+ const Maybe<AnimationParams>& aAnimParams = Nothing());
+
+ private:
+ /// Report that an error was encountered while decoding.
+ void PostError();
+
+ /**
+ * CompleteDecode() finishes up the decoding process after Decode() determines
+ * that we're finished. It records final progress and does all the cleanup
+ * that's possible off-main-thread.
+ */
+ void CompleteDecode();
+
+ /// @return the number of complete frames we have. Does not include the
+ /// current frame if it's unfinished.
+ uint32_t GetCompleteFrameCount() {
+ if (mFrameCount == 0) {
+ return 0;
+ }
+
+ return mInFrame ? mFrameCount - 1 : mFrameCount;
+ }
+
+ RawAccessFrameRef AllocateFrameInternal(
+ const gfx::IntSize& aOutputSize, gfx::SurfaceFormat aFormat,
+ const Maybe<AnimationParams>& aAnimParams,
+ RawAccessFrameRef&& aPreviousFrame);
+
+ protected:
+ /// Color management profile from the ICCP chunk in the image.
+ qcms_profile* mInProfile;
+
+ /// Color management transform to apply to image data.
+ qcms_transform* mTransform;
+
+ uint8_t* mImageData; // Pointer to image data in BGRA/X
+ uint32_t mImageDataLength;
+
+ CMSMode mCMSMode;
+
+ private:
+ RefPtr<RasterImage> mImage;
+ Maybe<SourceBufferIterator> mIterator;
+ IDecoderFrameRecycler* mFrameRecycler;
+
+ // The current frame the decoder is producing.
+ RawAccessFrameRef mCurrentFrame;
+
+ // The complete frame to combine with the current partial frame to produce
+ // a complete current frame.
+ RawAccessFrameRef mRestoreFrame;
+
+ ImageMetadata mImageMetadata;
+
+ OrientedIntRect
+ mInvalidRect; // Tracks new rows as the current frame is decoded.
+ gfx::IntRect mRestoreDirtyRect; // Tracks an invalidation region between the
+ // restore frame and the previous frame.
+ gfx::IntRect mRecycleRect; // Tracks an invalidation region between the
+ // recycled frame and the current frame.
+ Maybe<OrientedIntSize> mOutputSize; // The size of our output surface.
+ Maybe<OrientedIntSize> mExpectedSize; // The expected size of the image.
+ Progress mProgress;
+
+ uint32_t mFrameCount; // Number of frames, including anything in-progress
+ FrameTimeout mLoopLength; // Length of a single loop of this image.
+ gfx::IntRect
+ mFirstFrameRefreshArea; // The area of the image that needs to
+ // be invalidated when the animation loops.
+
+ // Telemetry data for this decoder.
+ TimeDuration mDecodeTime;
+
+ DecoderFlags mDecoderFlags;
+ SurfaceFlags mSurfaceFlags;
+
+ bool mInitialized : 1;
+ bool mMetadataDecode : 1;
+ bool mHaveExplicitOutputSize : 1;
+ bool mInFrame : 1;
+ bool mFinishedNewFrame : 1; // True if PostFrameStop() has been called since
+ // the last call to TakeCompleteFrameCount().
+ // Has a new frame that AnimationSurfaceProvider can take. Unfortunately this
+ // has to be separate from mFinishedNewFrame because the png decoder yields a
+ // new frame before calling PostFrameStop().
+ bool mHasFrameToTake : 1;
+ bool mReachedTerminalState : 1;
+ bool mDecodeDone : 1;
+ bool mError : 1;
+ bool mShouldReportError : 1;
+ bool mFinalizeFrames : 1;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_Decoder_h
diff --git a/image/DecoderFactory.cpp b/image/DecoderFactory.cpp
new file mode 100644
index 0000000000..4ee7fdfd22
--- /dev/null
+++ b/image/DecoderFactory.cpp
@@ -0,0 +1,446 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "DecoderFactory.h"
+
+#include "nsMimeTypes.h"
+#include "mozilla/RefPtr.h"
+
+#include "AnimationSurfaceProvider.h"
+#include "Decoder.h"
+#include "DecodedSurfaceProvider.h"
+#include "IDecodingTask.h"
+#include "ImageOps.h"
+#include "nsPNGDecoder.h"
+#include "nsGIFDecoder2.h"
+#include "nsJPEGDecoder.h"
+#include "nsBMPDecoder.h"
+#include "nsICODecoder.h"
+#include "nsIconDecoder.h"
+#include "nsWebPDecoder.h"
+#ifdef MOZ_AV1
+# include "nsAVIFDecoder.h"
+#endif
+#ifdef MOZ_JXL
+# include "nsJXLDecoder.h"
+#endif
+
+namespace mozilla {
+
+using namespace gfx;
+
+namespace image {
+
+/* static */
+DecoderType DecoderFactory::GetDecoderType(const char* aMimeType) {
+ // By default we don't know.
+ DecoderType type = DecoderType::UNKNOWN;
+
+ // PNG
+ if (!strcmp(aMimeType, IMAGE_PNG)) {
+ type = DecoderType::PNG;
+ } else if (!strcmp(aMimeType, IMAGE_X_PNG)) {
+ type = DecoderType::PNG;
+ } else if (!strcmp(aMimeType, IMAGE_APNG)) {
+ type = DecoderType::PNG;
+
+ // GIF
+ } else if (!strcmp(aMimeType, IMAGE_GIF)) {
+ type = DecoderType::GIF;
+
+ // JPEG
+ } else if (!strcmp(aMimeType, IMAGE_JPEG)) {
+ type = DecoderType::JPEG;
+ } else if (!strcmp(aMimeType, IMAGE_PJPEG)) {
+ type = DecoderType::JPEG;
+ } else if (!strcmp(aMimeType, IMAGE_JPG)) {
+ type = DecoderType::JPEG;
+
+ // BMP
+ } else if (!strcmp(aMimeType, IMAGE_BMP)) {
+ type = DecoderType::BMP;
+ } else if (!strcmp(aMimeType, IMAGE_BMP_MS)) {
+ type = DecoderType::BMP;
+
+ // BMP_CLIPBOARD
+ } else if (!strcmp(aMimeType, IMAGE_BMP_MS_CLIPBOARD)) {
+ type = DecoderType::BMP_CLIPBOARD;
+
+ // ICO
+ } else if (!strcmp(aMimeType, IMAGE_ICO)) {
+ type = DecoderType::ICO;
+ } else if (!strcmp(aMimeType, IMAGE_ICO_MS)) {
+ type = DecoderType::ICO;
+
+ // Icon
+ } else if (!strcmp(aMimeType, IMAGE_ICON_MS)) {
+ type = DecoderType::ICON;
+
+ // WebP
+ } else if (!strcmp(aMimeType, IMAGE_WEBP) &&
+ StaticPrefs::image_webp_enabled()) {
+ type = DecoderType::WEBP;
+
+ // AVIF
+ }
+#ifdef MOZ_AV1
+ else if (!strcmp(aMimeType, IMAGE_AVIF) &&
+ StaticPrefs::image_avif_enabled()) {
+ type = DecoderType::AVIF;
+ }
+#endif
+#ifdef MOZ_JXL
+ else if (!strcmp(aMimeType, IMAGE_JXL) && StaticPrefs::image_jxl_enabled()) {
+ type = DecoderType::JXL;
+ }
+#endif
+
+ return type;
+}
+
+/* static */
+DecoderFlags DecoderFactory::GetDefaultDecoderFlagsForType(DecoderType aType) {
+ auto flags = DefaultDecoderFlags();
+
+#ifdef MOZ_AV1
+ if (aType == DecoderType::AVIF) {
+ if (StaticPrefs::image_avif_sequence_enabled()) {
+ flags |= DecoderFlags::AVIF_SEQUENCES_ENABLED;
+ }
+ if (StaticPrefs::image_avif_sequence_animate_avif_major_branded_images()) {
+ flags |= DecoderFlags::AVIF_ANIMATE_AVIF_MAJOR;
+ }
+ }
+#endif
+
+ return flags;
+}
+
+/* static */
+already_AddRefed<Decoder> DecoderFactory::GetDecoder(DecoderType aType,
+ RasterImage* aImage,
+ bool aIsRedecode) {
+ RefPtr<Decoder> decoder;
+
+ switch (aType) {
+ case DecoderType::PNG:
+ decoder = new nsPNGDecoder(aImage);
+ break;
+ case DecoderType::GIF:
+ decoder = new nsGIFDecoder2(aImage);
+ break;
+ case DecoderType::JPEG:
+ // If we have all the data we don't want to waste cpu time doing
+ // a progressive decode.
+ decoder = new nsJPEGDecoder(
+ aImage, aIsRedecode ? Decoder::SEQUENTIAL : Decoder::PROGRESSIVE);
+ break;
+ case DecoderType::BMP:
+ decoder = new nsBMPDecoder(aImage);
+ break;
+ case DecoderType::BMP_CLIPBOARD:
+ decoder = new nsBMPDecoder(aImage, /* aForClipboard */ true);
+ break;
+ case DecoderType::ICO:
+ decoder = new nsICODecoder(aImage);
+ break;
+ case DecoderType::ICON:
+ decoder = new nsIconDecoder(aImage);
+ break;
+ case DecoderType::WEBP:
+ decoder = new nsWebPDecoder(aImage);
+ break;
+#ifdef MOZ_AV1
+ case DecoderType::AVIF:
+ decoder = new nsAVIFDecoder(aImage);
+ break;
+#endif
+#ifdef MOZ_JXL
+ case DecoderType::JXL:
+ decoder = new nsJXLDecoder(aImage);
+ break;
+#endif
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unknown decoder type");
+ }
+
+ return decoder.forget();
+}
+
+/* static */
+nsresult DecoderFactory::CreateDecoder(
+ DecoderType aType, NotNull<RasterImage*> aImage,
+ NotNull<SourceBuffer*> aSourceBuffer, const IntSize& aIntrinsicSize,
+ const IntSize& aOutputSize, DecoderFlags aDecoderFlags,
+ SurfaceFlags aSurfaceFlags, IDecodingTask** aOutTask) {
+ if (aType == DecoderType::UNKNOWN) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // Create an anonymous decoder. Interaction with the SurfaceCache and the
+ // owning RasterImage will be mediated by DecodedSurfaceProvider.
+ RefPtr<Decoder> decoder = GetDecoder(
+ aType, nullptr, bool(aDecoderFlags & DecoderFlags::IS_REDECODE));
+ MOZ_ASSERT(decoder, "Should have a decoder now");
+
+ // Initialize the decoder.
+ decoder->SetMetadataDecode(false);
+ decoder->SetIterator(aSourceBuffer->Iterator());
+ decoder->SetOutputSize(OrientedIntSize::FromUnknownSize(aOutputSize));
+ decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::FIRST_FRAME_ONLY);
+ decoder->SetSurfaceFlags(aSurfaceFlags);
+
+ nsresult rv = decoder->Init();
+ if (NS_FAILED(rv)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Create a DecodedSurfaceProvider which will manage the decoding process and
+ // make this decoder's output available in the surface cache.
+ SurfaceKey surfaceKey =
+ RasterSurfaceKey(aOutputSize, aSurfaceFlags, PlaybackType::eStatic);
+ auto provider = MakeNotNull<RefPtr<DecodedSurfaceProvider>>(
+ aImage, surfaceKey, WrapNotNull(decoder));
+ if (aDecoderFlags & DecoderFlags::CANNOT_SUBSTITUTE) {
+ provider->Availability().SetCannotSubstitute();
+ }
+
+ // Attempt to insert the surface provider into the surface cache right away so
+ // we won't trigger any more decoders with the same parameters.
+ switch (SurfaceCache::Insert(provider)) {
+ case InsertOutcome::SUCCESS:
+ break;
+ case InsertOutcome::FAILURE_ALREADY_PRESENT:
+ return NS_ERROR_ALREADY_INITIALIZED;
+ default:
+ return NS_ERROR_FAILURE;
+ }
+
+ // Return the surface provider in its IDecodingTask guise.
+ RefPtr<IDecodingTask> task = provider.get();
+ task.forget(aOutTask);
+ return NS_OK;
+}
+
+/* static */
+nsresult DecoderFactory::CreateAnimationDecoder(
+ DecoderType aType, NotNull<RasterImage*> aImage,
+ NotNull<SourceBuffer*> aSourceBuffer, const IntSize& aIntrinsicSize,
+ DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags,
+ size_t aCurrentFrame, IDecodingTask** aOutTask) {
+ if (aType == DecoderType::UNKNOWN) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ MOZ_ASSERT(aType == DecoderType::GIF || aType == DecoderType::PNG ||
+ aType == DecoderType::WEBP || aType == DecoderType::AVIF,
+ "Calling CreateAnimationDecoder for non-animating DecoderType");
+
+ // Create an anonymous decoder. Interaction with the SurfaceCache and the
+ // owning RasterImage will be mediated by AnimationSurfaceProvider.
+ RefPtr<Decoder> decoder =
+ GetDecoder(aType, nullptr, /* aIsRedecode = */ true);
+ MOZ_ASSERT(decoder, "Should have a decoder now");
+
+ // Initialize the decoder.
+ decoder->SetMetadataDecode(false);
+ decoder->SetIterator(aSourceBuffer->Iterator());
+ decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::IS_REDECODE);
+ decoder->SetSurfaceFlags(aSurfaceFlags);
+
+ nsresult rv = decoder->Init();
+ if (NS_FAILED(rv)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Create an AnimationSurfaceProvider which will manage the decoding process
+ // and make this decoder's output available in the surface cache.
+ SurfaceKey surfaceKey =
+ RasterSurfaceKey(aIntrinsicSize, aSurfaceFlags, PlaybackType::eAnimated);
+ auto provider = MakeNotNull<RefPtr<AnimationSurfaceProvider>>(
+ aImage, surfaceKey, WrapNotNull(decoder), aCurrentFrame);
+
+ // Attempt to insert the surface provider into the surface cache right away so
+ // we won't trigger any more decoders with the same parameters.
+ switch (SurfaceCache::Insert(provider)) {
+ case InsertOutcome::SUCCESS:
+ break;
+ case InsertOutcome::FAILURE_ALREADY_PRESENT:
+ return NS_ERROR_ALREADY_INITIALIZED;
+ default:
+ return NS_ERROR_FAILURE;
+ }
+
+ // Return the surface provider in its IDecodingTask guise.
+ RefPtr<IDecodingTask> task = provider.get();
+ task.forget(aOutTask);
+ return NS_OK;
+}
+
+/* static */
+already_AddRefed<Decoder> DecoderFactory::CloneAnimationDecoder(
+ Decoder* aDecoder) {
+ MOZ_ASSERT(aDecoder);
+
+ // In an ideal world, we would assert aDecoder->HasAnimation() but we cannot.
+ // The decoder may not have detected it is animated yet (e.g. it did not even
+ // get scheduled yet, or it has only decoded the first frame and has yet to
+ // rediscover it is animated).
+ DecoderType type = aDecoder->GetType();
+ MOZ_ASSERT(type == DecoderType::GIF || type == DecoderType::PNG ||
+ type == DecoderType::WEBP || type == DecoderType::AVIF,
+ "Calling CloneAnimationDecoder for non-animating DecoderType");
+
+ RefPtr<Decoder> decoder = GetDecoder(type, nullptr, /* aIsRedecode = */ true);
+ MOZ_ASSERT(decoder, "Should have a decoder now");
+
+ // Initialize the decoder.
+ decoder->SetMetadataDecode(false);
+ decoder->SetIterator(aDecoder->GetSourceBuffer()->Iterator());
+ decoder->SetDecoderFlags(aDecoder->GetDecoderFlags());
+ decoder->SetSurfaceFlags(aDecoder->GetSurfaceFlags());
+ decoder->SetFrameRecycler(aDecoder->GetFrameRecycler());
+
+ if (NS_FAILED(decoder->Init())) {
+ return nullptr;
+ }
+
+ return decoder.forget();
+}
+
+/* static */
+already_AddRefed<IDecodingTask> DecoderFactory::CreateMetadataDecoder(
+ DecoderType aType, NotNull<RasterImage*> aImage, DecoderFlags aFlags,
+ NotNull<SourceBuffer*> aSourceBuffer) {
+ if (aType == DecoderType::UNKNOWN) {
+ return nullptr;
+ }
+
+ RefPtr<Decoder> decoder =
+ GetDecoder(aType, aImage, /* aIsRedecode = */ false);
+ MOZ_ASSERT(decoder, "Should have a decoder now");
+
+ // Initialize the decoder.
+ decoder->SetMetadataDecode(true);
+ decoder->SetDecoderFlags(aFlags);
+ decoder->SetIterator(aSourceBuffer->Iterator());
+
+ if (NS_FAILED(decoder->Init())) {
+ return nullptr;
+ }
+
+ RefPtr<IDecodingTask> task = new MetadataDecodingTask(WrapNotNull(decoder));
+ return task.forget();
+}
+
+/* static */
+already_AddRefed<Decoder> DecoderFactory::CreateDecoderForICOResource(
+ DecoderType aType, SourceBufferIterator&& aIterator,
+ NotNull<nsICODecoder*> aICODecoder, bool aIsMetadataDecode,
+ const Maybe<OrientedIntSize>& aExpectedSize,
+ const Maybe<uint32_t>& aDataOffset
+ /* = Nothing() */) {
+ // Create the decoder.
+ RefPtr<Decoder> decoder;
+ switch (aType) {
+ case DecoderType::BMP:
+ MOZ_ASSERT(aDataOffset);
+ decoder =
+ new nsBMPDecoder(aICODecoder->GetImageMaybeNull(), *aDataOffset);
+ break;
+
+ case DecoderType::PNG:
+ MOZ_ASSERT(!aDataOffset);
+ decoder = new nsPNGDecoder(aICODecoder->GetImageMaybeNull());
+ break;
+
+ default:
+ MOZ_ASSERT_UNREACHABLE("Invalid ICO resource decoder type");
+ return nullptr;
+ }
+
+ MOZ_ASSERT(decoder);
+
+ // Initialize the decoder, copying settings from @aICODecoder.
+ decoder->SetMetadataDecode(aIsMetadataDecode);
+ decoder->SetIterator(std::forward<SourceBufferIterator>(aIterator));
+ if (!aIsMetadataDecode) {
+ decoder->SetOutputSize(aICODecoder->OutputSize());
+ }
+ if (aExpectedSize) {
+ decoder->SetExpectedSize(*aExpectedSize);
+ }
+ decoder->SetDecoderFlags(aICODecoder->GetDecoderFlags());
+ decoder->SetSurfaceFlags(aICODecoder->GetSurfaceFlags());
+ decoder->SetFinalizeFrames(false);
+
+ if (NS_FAILED(decoder->Init())) {
+ return nullptr;
+ }
+
+ return decoder.forget();
+}
+
+/* static */
+already_AddRefed<Decoder> DecoderFactory::CreateAnonymousDecoder(
+ DecoderType aType, NotNull<SourceBuffer*> aSourceBuffer,
+ const Maybe<IntSize>& aOutputSize, DecoderFlags aDecoderFlags,
+ SurfaceFlags aSurfaceFlags) {
+ if (aType == DecoderType::UNKNOWN) {
+ return nullptr;
+ }
+
+ RefPtr<Decoder> decoder =
+ GetDecoder(aType, /* aImage = */ nullptr, /* aIsRedecode = */ false);
+ MOZ_ASSERT(decoder, "Should have a decoder now");
+
+ // Initialize the decoder.
+ decoder->SetMetadataDecode(false);
+ decoder->SetIterator(aSourceBuffer->Iterator());
+
+ // Anonymous decoders are always transient; we don't want to optimize surfaces
+ // or do any other expensive work that might be wasted.
+ DecoderFlags decoderFlags = DecoderFlags::IMAGE_IS_TRANSIENT;
+
+ decoder->SetDecoderFlags(aDecoderFlags | decoderFlags);
+ decoder->SetSurfaceFlags(aSurfaceFlags);
+
+ // Set an output size for downscale-during-decode if requested.
+ if (aOutputSize) {
+ decoder->SetOutputSize(OrientedIntSize::FromUnknownSize(*aOutputSize));
+ }
+
+ if (NS_FAILED(decoder->Init())) {
+ return nullptr;
+ }
+
+ return decoder.forget();
+}
+
+/* static */
+already_AddRefed<Decoder> DecoderFactory::CreateAnonymousMetadataDecoder(
+ DecoderType aType, NotNull<SourceBuffer*> aSourceBuffer) {
+ if (aType == DecoderType::UNKNOWN) {
+ return nullptr;
+ }
+
+ RefPtr<Decoder> decoder =
+ GetDecoder(aType, /* aImage = */ nullptr, /* aIsRedecode = */ false);
+ MOZ_ASSERT(decoder, "Should have a decoder now");
+
+ // Initialize the decoder.
+ decoder->SetMetadataDecode(true);
+ decoder->SetIterator(aSourceBuffer->Iterator());
+ decoder->SetDecoderFlags(DecoderFlags::FIRST_FRAME_ONLY);
+
+ if (NS_FAILED(decoder->Init())) {
+ return nullptr;
+ }
+
+ return decoder.forget();
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/DecoderFactory.h b/image/DecoderFactory.h
new file mode 100644
index 0000000000..bdf1cce02d
--- /dev/null
+++ b/image/DecoderFactory.h
@@ -0,0 +1,210 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_DecoderFactory_h
+#define mozilla_image_DecoderFactory_h
+
+#include "DecoderFlags.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/NotNull.h"
+#include "mozilla/gfx/2D.h"
+#include "nsCOMPtr.h"
+#include "Orientation.h"
+#include "SurfaceFlags.h"
+
+namespace mozilla::image {
+
+class Decoder;
+class IDecodingTask;
+class nsICODecoder;
+class RasterImage;
+class SourceBuffer;
+class SourceBufferIterator;
+
+/**
+ * The type of decoder; this is usually determined from a MIME type using
+ * DecoderFactory::GetDecoderType().
+ */
+enum class DecoderType {
+ PNG,
+ GIF,
+ JPEG,
+ BMP,
+ BMP_CLIPBOARD,
+ ICO,
+ ICON,
+ WEBP,
+ AVIF,
+ JXL,
+ UNKNOWN
+};
+
+class DecoderFactory {
+ public:
+ /// @return the type of decoder which is appropriate for @aMimeType.
+ static DecoderType GetDecoderType(const char* aMimeType);
+
+ /// @return the default flags to use when creating a decoder of @aType.
+ static DecoderFlags GetDefaultDecoderFlagsForType(DecoderType aType);
+
+ /**
+ * Creates and initializes a decoder for non-animated images of type @aType.
+ * (If the image *is* animated, only the first frame will be decoded.) The
+ * decoder will send notifications to @aImage.
+ *
+ * @param aType Which type of decoder to create - JPEG, PNG, etc.
+ * @param aImage The image will own the decoder and which should receive
+ * notifications as decoding progresses.
+ * @param aSourceBuffer The SourceBuffer which the decoder will read its data
+ * from.
+ * @param aIntrinsicSize The intrinsic size of the image, normally obtained
+ * during the metadata decode.
+ * @param aOutputSize The output size for the decoder. If this is smaller than
+ * the intrinsic size, the decoder will downscale the
+ * image.
+ * @param aDecoderFlags Flags specifying the behavior of this decoder.
+ * @param aSurfaceFlags Flags specifying the type of output this decoder
+ * should produce.
+ * @param aOutTask Task representing the decoder.
+ * @return NS_OK if the decoder has been created/initialized successfully;
+ * NS_ERROR_ALREADY_INITIALIZED if there is already an active decoder
+ * for this image;
+ * Else some other unrecoverable error occurred.
+ */
+ static nsresult CreateDecoder(DecoderType aType, NotNull<RasterImage*> aImage,
+ NotNull<SourceBuffer*> aSourceBuffer,
+ const gfx::IntSize& aIntrinsicSize,
+ const gfx::IntSize& aOutputSize,
+ DecoderFlags aDecoderFlags,
+ SurfaceFlags aSurfaceFlags,
+ IDecodingTask** aOutTask);
+
+ /**
+ * Creates and initializes a decoder for animated images of type @aType.
+ * The decoder will send notifications to @aImage.
+ *
+ * @param aType Which type of decoder to create - JPEG, PNG, etc.
+ * @param aImage The image will own the decoder and which should receive
+ * notifications as decoding progresses.
+ * @param aSourceBuffer The SourceBuffer which the decoder will read its data
+ * from.
+ * @param aIntrinsicSize The intrinsic size of the image, normally obtained
+ * during the metadata decode.
+ * @param aDecoderFlags Flags specifying the behavior of this decoder.
+ * @param aSurfaceFlags Flags specifying the type of output this decoder
+ * should produce.
+ * @param aCurrentFrame The current frame the decoder should auto advance to.
+ * @param aOutTask Task representing the decoder.
+ * @return NS_OK if the decoder has been created/initialized successfully;
+ * NS_ERROR_ALREADY_INITIALIZED if there is already an active decoder
+ * for this image;
+ * Else some other unrecoverable error occurred.
+ */
+ static nsresult CreateAnimationDecoder(
+ DecoderType aType, NotNull<RasterImage*> aImage,
+ NotNull<SourceBuffer*> aSourceBuffer, const gfx::IntSize& aIntrinsicSize,
+ DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags,
+ size_t aCurrentFrame, IDecodingTask** aOutTask);
+
+ /**
+ * Creates and initializes a decoder for animated images, cloned from the
+ * given decoder.
+ *
+ * @param aDecoder Decoder to clone.
+ */
+ static already_AddRefed<Decoder> CloneAnimationDecoder(Decoder* aDecoder);
+
+ /**
+ * Creates and initializes a metadata decoder of type @aType. This decoder
+ * will only decode the image's header, extracting metadata like the size of
+ * the image. No actual image data will be decoded and no surfaces will be
+ * allocated. The decoder will send notifications to @aImage.
+ *
+ * @param aType Which type of decoder to create - JPEG, PNG, etc.
+ * @param aImage The image will own the decoder and which should receive
+ * notifications as decoding progresses.
+ * @param aSourceBuffer The SourceBuffer which the decoder will read its data
+ * from.
+ */
+ static already_AddRefed<IDecodingTask> CreateMetadataDecoder(
+ DecoderType aType, NotNull<RasterImage*> aImage, DecoderFlags aFlags,
+ NotNull<SourceBuffer*> aSourceBuffer);
+
+ /**
+ * Creates and initializes a decoder for an ICO resource, which may be either
+ * a BMP or PNG image.
+ *
+ * @param aType Which type of decoder to create. This must be either BMP or
+ * PNG.
+ * @param aIterator The SourceBufferIterator which the decoder will read its
+ * data from.
+ * @param aICODecoder The ICO decoder which is controlling this resource
+ * decoder. @aICODecoder's settings will be copied to the
+ * resource decoder, so the two decoders will have the
+ * same decoder flags, surface flags, target size, and
+ * other parameters.
+ * @param aIsMetadataDecode Indicates whether or not this decoder is for
+ * metadata or not. Independent of the state of the
+ * parent decoder.
+ * @param aExpectedSize The expected size of the resource from the ICO header.
+ * @param aDataOffset If @aType is BMP, specifies the offset at which data
+ * begins in the BMP resource. Must be Some() if and only
+ * if @aType is BMP.
+ */
+ static already_AddRefed<Decoder> CreateDecoderForICOResource(
+ DecoderType aType, SourceBufferIterator&& aIterator,
+ NotNull<nsICODecoder*> aICODecoder, bool aIsMetadataDecode,
+ const Maybe<OrientedIntSize>& aExpectedSize,
+ const Maybe<uint32_t>& aDataOffset = Nothing());
+
+ /**
+ * Creates and initializes an anonymous decoder (one which isn't associated
+ * with an Image object). Only the first frame of the image will be decoded.
+ *
+ * @param aType Which type of decoder to create - JPEG, PNG, etc.
+ * @param aSourceBuffer The SourceBuffer which the decoder will read its data
+ * from.
+ * @param aOutputSize If Some(), the output size for the decoder. If this is
+ * smaller than the intrinsic size, the decoder will
+ * downscale the image. If Nothing(), the output size will
+ * be the intrinsic size.
+ * @param aDecoderFlags Flags specifying the behavior of this decoder.
+ * @param aSurfaceFlags Flags specifying the type of output this decoder
+ * should produce.
+ */
+ static already_AddRefed<Decoder> CreateAnonymousDecoder(
+ DecoderType aType, NotNull<SourceBuffer*> aSourceBuffer,
+ const Maybe<gfx::IntSize>& aOutputSize, DecoderFlags aDecoderFlags,
+ SurfaceFlags aSurfaceFlags);
+
+ /**
+ * Creates and initializes an anonymous metadata decoder (one which isn't
+ * associated with an Image object). This decoder will only decode the image's
+ * header, extracting metadata like the size of the image. No actual image
+ * data will be decoded and no surfaces will be allocated.
+ *
+ * @param aType Which type of decoder to create - JPEG, PNG, etc.
+ * @param aSourceBuffer The SourceBuffer which the decoder will read its data
+ * from.
+ */
+ static already_AddRefed<Decoder> CreateAnonymousMetadataDecoder(
+ DecoderType aType, NotNull<SourceBuffer*> aSourceBuffer);
+
+ private:
+ virtual ~DecoderFactory() = 0;
+
+ /**
+ * An internal method which allocates a new decoder of the requested @aType.
+ */
+ static already_AddRefed<Decoder> GetDecoder(DecoderType aType,
+ RasterImage* aImage,
+ bool aIsRedecode);
+};
+
+} // namespace mozilla::image
+
+#endif // mozilla_image_DecoderFactory_h
diff --git a/image/DecoderFlags.h b/image/DecoderFlags.h
new file mode 100644
index 0000000000..778cdd2942
--- /dev/null
+++ b/image/DecoderFlags.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_DecoderFlags_h
+#define mozilla_image_DecoderFlags_h
+
+#include "mozilla/TypedEnumBits.h"
+
+namespace mozilla {
+namespace image {
+
+/**
+ * Flags that influence decoder behavior. Note that these flags *don't*
+ * influence the logical content of the surfaces that the decoder generates, so
+ * they're not in a factor in SurfaceCache lookups and the like. These flags
+ * instead either influence which surfaces are generated at all or the tune the
+ * decoder's behavior for a particular scenario.
+ */
+enum class DecoderFlags : uint8_t {
+ FIRST_FRAME_ONLY = 1 << 0,
+ IS_REDECODE = 1 << 1,
+ IMAGE_IS_TRANSIENT = 1 << 2,
+ ASYNC_NOTIFY = 1 << 3,
+
+ /**
+ * By default, a surface is considered substitutable. That means callers are
+ * willing to accept a less than ideal match to display. If a caller requires
+ * a specific size and won't accept alternatives, then this flag should be
+ * set.
+ */
+ CANNOT_SUBSTITUTE = 1 << 4,
+
+#ifdef MOZ_AV1
+ // The flags below are stored in RasterImage to allow a decoded image to
+ // remain consistent in whether it is animated or not.
+
+ // Set according to the "image.avif.sequence.enabled" preference.
+ AVIF_SEQUENCES_ENABLED = 1 << 5,
+ // Set according to the
+ // "image.avif.sequence.animate_avif_major_branded_images" preference.
+ AVIF_ANIMATE_AVIF_MAJOR = 1 << 6,
+#endif
+};
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DecoderFlags)
+
+/**
+ * @return the default set of decode flags.
+ */
+inline DecoderFlags DefaultDecoderFlags() { return DecoderFlags(); }
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_DecoderFlags_h
diff --git a/image/Downscaler.cpp b/image/Downscaler.cpp
new file mode 100644
index 0000000000..5bf15f1469
--- /dev/null
+++ b/image/Downscaler.cpp
@@ -0,0 +1,302 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "Downscaler.h"
+
+#include <algorithm>
+#include <ctime>
+
+#include "mozilla/gfx/2D.h"
+
+using std::max;
+using std::swap;
+
+namespace mozilla {
+
+using gfx::IntRect;
+
+namespace image {
+
+Downscaler::Downscaler(const nsIntSize& aTargetSize)
+ : mTargetSize(aTargetSize),
+ mOutputBuffer(nullptr),
+ mWindowCapacity(0),
+ mLinesInBuffer(0),
+ mPrevInvalidatedLine(0),
+ mCurrentOutLine(0),
+ mCurrentInLine(0),
+ mHasAlpha(true),
+ mFlipVertically(false) {
+ MOZ_ASSERT(mTargetSize.width > 0 && mTargetSize.height > 0,
+ "Invalid target size");
+}
+
+Downscaler::~Downscaler() { ReleaseWindow(); }
+
+void Downscaler::ReleaseWindow() {
+ if (!mWindow) {
+ return;
+ }
+
+ for (int32_t i = 0; i < mWindowCapacity; ++i) {
+ delete[] mWindow[i];
+ }
+
+ mWindow = nullptr;
+ mWindowCapacity = 0;
+}
+
+nsresult Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
+ const Maybe<nsIntRect>& aFrameRect,
+ uint8_t* aOutputBuffer, bool aHasAlpha,
+ bool aFlipVertically /* = false */) {
+ MOZ_ASSERT(aOutputBuffer);
+ MOZ_ASSERT(mTargetSize != aOriginalSize,
+ "Created a downscaler, but not downscaling?");
+ MOZ_ASSERT(mTargetSize.width <= aOriginalSize.width,
+ "Created a downscaler, but width is larger");
+ MOZ_ASSERT(mTargetSize.height <= aOriginalSize.height,
+ "Created a downscaler, but height is larger");
+ MOZ_ASSERT(aOriginalSize.width > 0 && aOriginalSize.height > 0,
+ "Invalid original size");
+
+ // Only downscale from reasonable sizes to avoid using too much memory/cpu
+ // downscaling and decoding. 1 << 20 == 1,048,576 seems a reasonable limit.
+ if (aOriginalSize.width > (1 << 20) || aOriginalSize.height > (1 << 20)) {
+ NS_WARNING("Trying to downscale image frame that is too large");
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ mFrameRect = aFrameRect.valueOr(nsIntRect(nsIntPoint(), aOriginalSize));
+ MOZ_ASSERT(mFrameRect.X() >= 0 && mFrameRect.Y() >= 0 &&
+ mFrameRect.Width() >= 0 && mFrameRect.Height() >= 0,
+ "Frame rect must have non-negative components");
+ MOZ_ASSERT(nsIntRect(0, 0, aOriginalSize.width, aOriginalSize.height)
+ .Contains(mFrameRect),
+ "Frame rect must fit inside image");
+ MOZ_ASSERT_IF(!nsIntRect(0, 0, aOriginalSize.width, aOriginalSize.height)
+ .IsEqualEdges(mFrameRect),
+ aHasAlpha);
+
+ mOriginalSize = aOriginalSize;
+ mScale = gfx::MatrixScalesDouble(
+ double(mOriginalSize.width) / mTargetSize.width,
+ double(mOriginalSize.height) / mTargetSize.height);
+ mOutputBuffer = aOutputBuffer;
+ mHasAlpha = aHasAlpha;
+ mFlipVertically = aFlipVertically;
+
+ ReleaseWindow();
+
+ auto resizeMethod = gfx::ConvolutionFilter::ResizeMethod::LANCZOS3;
+ if (!mXFilter.ComputeResizeFilter(resizeMethod, mOriginalSize.width,
+ mTargetSize.width) ||
+ !mYFilter.ComputeResizeFilter(resizeMethod, mOriginalSize.height,
+ mTargetSize.height)) {
+ NS_WARNING("Failed to compute filters for image downscaling");
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ // Allocate the buffer, which contains scanlines of the original image.
+ // pad to handle overreads by the simd code
+ size_t bufferLen = gfx::ConvolutionFilter::PadBytesForSIMD(
+ mOriginalSize.width * sizeof(uint32_t));
+ mRowBuffer.reset(new (fallible) uint8_t[bufferLen]);
+ if (MOZ_UNLIKELY(!mRowBuffer)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ // Zero buffer to keep valgrind happy.
+ memset(mRowBuffer.get(), 0, bufferLen);
+
+ // Allocate the window, which contains horizontally downscaled scanlines. (We
+ // can store scanlines which are already downscale because our downscaling
+ // filter is separable.)
+ mWindowCapacity = mYFilter.MaxFilter();
+ mWindow.reset(new (fallible) uint8_t*[mWindowCapacity]);
+ if (MOZ_UNLIKELY(!mWindow)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ bool anyAllocationFailed = false;
+ // pad to handle overreads by the simd code
+ const size_t rowSize = gfx::ConvolutionFilter::PadBytesForSIMD(
+ mTargetSize.width * sizeof(uint32_t));
+ for (int32_t i = 0; i < mWindowCapacity; ++i) {
+ mWindow[i] = new (fallible) uint8_t[rowSize];
+ anyAllocationFailed = anyAllocationFailed || mWindow[i] == nullptr;
+ }
+
+ if (MOZ_UNLIKELY(anyAllocationFailed)) {
+ // We intentionally iterate through the entire array even if an allocation
+ // fails, to ensure that all the pointers in it are either valid or nullptr.
+ // That in turn ensures that ReleaseWindow() can clean up correctly.
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ ResetForNextProgressivePass();
+
+ return NS_OK;
+}
+
+void Downscaler::SkipToRow(int32_t aRow) {
+ if (mCurrentInLine < aRow) {
+ ClearRow();
+ do {
+ CommitRow();
+ } while (mCurrentInLine < aRow);
+ }
+}
+
+void Downscaler::ResetForNextProgressivePass() {
+ mPrevInvalidatedLine = 0;
+ mCurrentOutLine = 0;
+ mCurrentInLine = 0;
+ mLinesInBuffer = 0;
+
+ if (mFrameRect.IsEmpty()) {
+ // Our frame rect is zero size; commit rows until the end of the image.
+ SkipToRow(mOriginalSize.height - 1);
+ } else {
+ // If we have a vertical offset, commit rows to shift us past it.
+ SkipToRow(mFrameRect.Y());
+ }
+}
+
+void Downscaler::ClearRestOfRow(uint32_t aStartingAtCol) {
+ MOZ_ASSERT(int64_t(aStartingAtCol) <= int64_t(mOriginalSize.width));
+ uint32_t bytesToClear =
+ (mOriginalSize.width - aStartingAtCol) * sizeof(uint32_t);
+ memset(mRowBuffer.get() + (aStartingAtCol * sizeof(uint32_t)), 0,
+ bytesToClear);
+}
+
+void Downscaler::CommitRow() {
+ MOZ_ASSERT(mOutputBuffer, "Should have a current frame");
+ MOZ_ASSERT(mCurrentInLine < mOriginalSize.height, "Past end of input");
+
+ if (mCurrentOutLine < mTargetSize.height) {
+ int32_t filterOffset = 0;
+ int32_t filterLength = 0;
+ mYFilter.GetFilterOffsetAndLength(mCurrentOutLine, &filterOffset,
+ &filterLength);
+
+ int32_t inLineToRead = filterOffset + mLinesInBuffer;
+ MOZ_ASSERT(mCurrentInLine <= inLineToRead, "Reading past end of input");
+ if (mCurrentInLine == inLineToRead) {
+ MOZ_RELEASE_ASSERT(mLinesInBuffer < mWindowCapacity,
+ "Need more rows than capacity!");
+ mXFilter.ConvolveHorizontally(mRowBuffer.get(), mWindow[mLinesInBuffer++],
+ mHasAlpha);
+ }
+
+ MOZ_ASSERT(mCurrentOutLine < mTargetSize.height,
+ "Writing past end of output");
+
+ while (mLinesInBuffer >= filterLength) {
+ DownscaleInputLine();
+
+ if (mCurrentOutLine == mTargetSize.height) {
+ break; // We're done.
+ }
+
+ mYFilter.GetFilterOffsetAndLength(mCurrentOutLine, &filterOffset,
+ &filterLength);
+ }
+ }
+
+ mCurrentInLine += 1;
+
+ // If we're at the end of the part of the original image that has data, commit
+ // rows to shift us to the end.
+ if (mCurrentInLine == (mFrameRect.Y() + mFrameRect.Height())) {
+ SkipToRow(mOriginalSize.height - 1);
+ }
+}
+
+bool Downscaler::HasInvalidation() const {
+ return mCurrentOutLine > mPrevInvalidatedLine;
+}
+
+DownscalerInvalidRect Downscaler::TakeInvalidRect() {
+ if (MOZ_UNLIKELY(!HasInvalidation())) {
+ return DownscalerInvalidRect();
+ }
+
+ DownscalerInvalidRect invalidRect;
+
+ // Compute the target size invalid rect.
+ if (mFlipVertically) {
+ // We need to flip it. This will implicitly flip the original size invalid
+ // rect, since we compute it by scaling this rect.
+ invalidRect.mTargetSizeRect =
+ IntRect(0, mTargetSize.height - mCurrentOutLine, mTargetSize.width,
+ mCurrentOutLine - mPrevInvalidatedLine);
+ } else {
+ invalidRect.mTargetSizeRect =
+ IntRect(0, mPrevInvalidatedLine, mTargetSize.width,
+ mCurrentOutLine - mPrevInvalidatedLine);
+ }
+
+ mPrevInvalidatedLine = mCurrentOutLine;
+
+ // Compute the original size invalid rect.
+ invalidRect.mOriginalSizeRect = invalidRect.mTargetSizeRect;
+ invalidRect.mOriginalSizeRect.ScaleRoundOut(mScale.xScale, mScale.yScale);
+
+ return invalidRect;
+}
+
+void Downscaler::DownscaleInputLine() {
+ MOZ_ASSERT(mOutputBuffer);
+ MOZ_ASSERT(mCurrentOutLine < mTargetSize.height,
+ "Writing past end of output");
+
+ int32_t filterOffset = 0;
+ int32_t filterLength = 0;
+ mYFilter.GetFilterOffsetAndLength(mCurrentOutLine, &filterOffset,
+ &filterLength);
+
+ int32_t currentOutLine = mFlipVertically
+ ? mTargetSize.height - (mCurrentOutLine + 1)
+ : mCurrentOutLine;
+ MOZ_ASSERT(currentOutLine >= 0);
+
+ uint8_t* outputLine =
+ &mOutputBuffer[currentOutLine * mTargetSize.width * sizeof(uint32_t)];
+ mYFilter.ConvolveVertically(mWindow.get(), outputLine, mCurrentOutLine,
+ mXFilter.NumValues(), mHasAlpha);
+
+ mCurrentOutLine += 1;
+
+ if (mCurrentOutLine == mTargetSize.height) {
+ // We're done.
+ return;
+ }
+
+ int32_t newFilterOffset = 0;
+ int32_t newFilterLength = 0;
+ mYFilter.GetFilterOffsetAndLength(mCurrentOutLine, &newFilterOffset,
+ &newFilterLength);
+
+ int diff = newFilterOffset - filterOffset;
+ MOZ_ASSERT(diff >= 0, "Moving backwards in the filter?");
+
+ // Shift the buffer. We're just moving pointers here, so this is cheap.
+ mLinesInBuffer -= diff;
+ mLinesInBuffer = std::min(std::max(mLinesInBuffer, 0), mWindowCapacity);
+
+ // If we already have enough rows to satisfy the filter, there is no need
+ // to swap as we won't be writing more before the next convolution.
+ if (filterLength > mLinesInBuffer) {
+ for (int32_t i = 0; i < mLinesInBuffer; ++i) {
+ swap(mWindow[i], mWindow[filterLength - mLinesInBuffer + i]);
+ }
+ }
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/Downscaler.h b/image/Downscaler.h
new file mode 100644
index 0000000000..e5fcf0387e
--- /dev/null
+++ b/image/Downscaler.h
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Downscaler is a high-quality, streaming image downscaler based upon Skia's
+ * scaling implementation.
+ */
+
+#ifndef mozilla_image_Downscaler_h
+#define mozilla_image_Downscaler_h
+
+#include "mozilla/Maybe.h"
+#include "mozilla/UniquePtr.h"
+#include "gfxPoint.h"
+#include "nsRect.h"
+#include "mozilla/gfx/ConvolutionFilter.h"
+#include "mozilla/gfx/Matrix.h"
+
+namespace mozilla {
+namespace image {
+
+/**
+ * DownscalerInvalidRect wraps two invalidation rects: one in terms of the
+ * original image size, and one in terms of the target size.
+ */
+struct DownscalerInvalidRect {
+ nsIntRect mOriginalSizeRect;
+ nsIntRect mTargetSizeRect;
+};
+
+/**
+ * Downscaler is a high-quality, streaming image downscaler based upon Skia's
+ * scaling implementation.
+ *
+ * Decoders can construct a Downscaler once they know their target size, then
+ * call BeginFrame() for each frame they decode. They should write a decoded row
+ * into the buffer returned by RowBuffer(), and then call CommitRow() to signal
+ * that they have finished.
+ *
+
+ * Because invalidations need to be computed in terms of the scaled version of
+ * the image, Downscaler also tracks them. Decoders can call HasInvalidation()
+ * and TakeInvalidRect() instead of tracking invalidations themselves.
+ */
+class Downscaler {
+ public:
+ /// Constructs a new Downscaler which to scale to size @aTargetSize.
+ explicit Downscaler(const nsIntSize& aTargetSize);
+ ~Downscaler();
+
+ const nsIntSize& OriginalSize() const { return mOriginalSize; }
+ const nsIntSize& TargetSize() const { return mTargetSize; }
+ const nsIntSize FrameSize() const {
+ return nsIntSize(mFrameRect.Width(), mFrameRect.Height());
+ }
+ const gfx::MatrixScalesDouble& Scale() const { return mScale; }
+
+ /**
+ * Begins a new frame and reinitializes the Downscaler.
+ *
+ * @param aOriginalSize The original size of this frame, before scaling.
+ * @param aFrameRect The region of the original image which has data.
+ * Every pixel outside @aFrameRect is considered blank and
+ * has zero alpha.
+ * @param aOutputBuffer The buffer to which the Downscaler should write its
+ * output; this is the same buffer where the Decoder
+ * would write its output when not downscaling during
+ * decode.
+ * @param aHasAlpha Whether or not this frame has an alpha channel.
+ * Performance is a little better if it doesn't have one.
+ * @param aFlipVertically If true, output rows will be written to the output
+ * buffer in reverse order vertically, which matches
+ * the way they are stored in some image formats.
+ */
+ nsresult BeginFrame(const nsIntSize& aOriginalSize,
+ const Maybe<nsIntRect>& aFrameRect,
+ uint8_t* aOutputBuffer, bool aHasAlpha,
+ bool aFlipVertically = false);
+
+ bool IsFrameComplete() const {
+ return mCurrentInLine >= mOriginalSize.height;
+ }
+
+ /// Retrieves the buffer into which the Decoder should write each row.
+ uint8_t* RowBuffer() {
+ return mRowBuffer.get() + mFrameRect.X() * sizeof(uint32_t);
+ }
+
+ /// Clears the current row buffer.
+ void ClearRow() { ClearRestOfRow(0); }
+
+ /// Clears the current row buffer starting at @aStartingAtCol.
+ void ClearRestOfRow(uint32_t aStartingAtCol);
+
+ /// Signals that the decoder has finished writing a row into the row buffer.
+ void CommitRow();
+
+ /// Returns true if there is a non-empty invalid rect available.
+ bool HasInvalidation() const;
+
+ /// Takes the Downscaler's current invalid rect and resets it.
+ DownscalerInvalidRect TakeInvalidRect();
+
+ /**
+ * Resets the Downscaler's position in the image, for a new progressive pass
+ * over the same frame. Because the same data structures can be reused, this
+ * is more efficient than calling BeginFrame.
+ */
+ void ResetForNextProgressivePass();
+
+ private:
+ void DownscaleInputLine();
+ void ReleaseWindow();
+ void SkipToRow(int32_t aRow);
+
+ nsIntSize mOriginalSize;
+ nsIntSize mTargetSize;
+ nsIntRect mFrameRect;
+ gfx::MatrixScalesDouble mScale;
+
+ uint8_t* mOutputBuffer;
+
+ UniquePtr<uint8_t[]> mRowBuffer;
+ UniquePtr<uint8_t*[]> mWindow;
+
+ gfx::ConvolutionFilter mXFilter;
+ gfx::ConvolutionFilter mYFilter;
+
+ int32_t mWindowCapacity;
+
+ int32_t mLinesInBuffer;
+ int32_t mPrevInvalidatedLine;
+ int32_t mCurrentOutLine;
+ int32_t mCurrentInLine;
+
+ bool mHasAlpha : 1;
+ bool mFlipVertically : 1;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_Downscaler_h
diff --git a/image/DownscalingFilter.h b/image/DownscalingFilter.h
new file mode 100644
index 0000000000..1233e7be0b
--- /dev/null
+++ b/image/DownscalingFilter.h
@@ -0,0 +1,312 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * DownscalingSurfaceFilter is a SurfaceFilter implementation for use with
+ * SurfacePipe which performs Lanczos downscaling.
+ *
+ * It's in this header file, separated from the other SurfaceFilters, because
+ * some preprocessor magic is necessary to ensure that there aren't compilation
+ * issues on platforms where Skia is unavailable.
+ */
+
+#ifndef mozilla_image_DownscalingFilter_h
+#define mozilla_image_DownscalingFilter_h
+
+#include <algorithm>
+#include <ctime>
+#include <stdint.h>
+
+#include "mozilla/Maybe.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/gfx/2D.h"
+
+#include "mozilla/gfx/ConvolutionFilter.h"
+
+#include "SurfacePipe.h"
+
+namespace mozilla {
+namespace image {
+
+//////////////////////////////////////////////////////////////////////////////
+// DownscalingFilter
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename Next>
+class DownscalingFilter;
+
+/**
+ * A configuration struct for DownscalingConfig.
+ */
+struct DownscalingConfig {
+ template <typename Next>
+ using Filter = DownscalingFilter<Next>;
+ gfx::IntSize mInputSize; /// The size of the input image. We'll downscale
+ /// from this size to the input size of the next
+ /// SurfaceFilter in the chain.
+ gfx::SurfaceFormat mFormat; /// The pixel format - BGRA or BGRX. (BGRX has
+ /// slightly better performance.)
+};
+
+/**
+ * DownscalingFilter performs Lanczos downscaling, taking image input data at
+ * one size and outputting it rescaled to a different size.
+ *
+ * The 'Next' template parameter specifies the next filter in the chain.
+ */
+template <typename Next>
+class DownscalingFilter final : public SurfaceFilter {
+ public:
+ DownscalingFilter()
+ : mWindowCapacity(0),
+ mRowsInWindow(0),
+ mInputRow(0),
+ mOutputRow(0),
+ mHasAlpha(true) {}
+
+ ~DownscalingFilter() { ReleaseWindow(); }
+
+ template <typename... Rest>
+ nsresult Configure(const DownscalingConfig& aConfig, const Rest&... aRest) {
+ nsresult rv = mNext.Configure(aRest...);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ if (mNext.InputSize() == aConfig.mInputSize) {
+ NS_WARNING("Created a downscaler, but not downscaling?");
+ return NS_ERROR_INVALID_ARG;
+ }
+ if (mNext.InputSize().width > aConfig.mInputSize.width) {
+ NS_WARNING("Created a downscaler, but width is larger");
+ return NS_ERROR_INVALID_ARG;
+ }
+ if (mNext.InputSize().height > aConfig.mInputSize.height) {
+ NS_WARNING("Created a downscaler, but height is larger");
+ return NS_ERROR_INVALID_ARG;
+ }
+ if (aConfig.mInputSize.width <= 0 || aConfig.mInputSize.height <= 0) {
+ NS_WARNING("Invalid input size for DownscalingFilter");
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ mInputSize = aConfig.mInputSize;
+ gfx::IntSize outputSize = mNext.InputSize();
+ mScale =
+ gfx::MatrixScalesDouble(double(mInputSize.width) / outputSize.width,
+ double(mInputSize.height) / outputSize.height);
+ mHasAlpha = aConfig.mFormat == gfx::SurfaceFormat::OS_RGBA;
+
+ ReleaseWindow();
+
+ auto resizeMethod = gfx::ConvolutionFilter::ResizeMethod::LANCZOS3;
+ if (!mXFilter.ComputeResizeFilter(resizeMethod, mInputSize.width,
+ outputSize.width) ||
+ !mYFilter.ComputeResizeFilter(resizeMethod, mInputSize.height,
+ outputSize.height)) {
+ NS_WARNING("Failed to compute filters for image downscaling");
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ // Allocate the buffer, which contains scanlines of the input image.
+ mRowBuffer.reset(new (fallible)
+ uint8_t[PaddedWidthInBytes(mInputSize.width)]);
+ if (MOZ_UNLIKELY(!mRowBuffer)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ // Clear the buffer to avoid writing uninitialized memory to the output.
+ memset(mRowBuffer.get(), 0, PaddedWidthInBytes(mInputSize.width));
+
+ // Allocate the window, which contains horizontally downscaled scanlines.
+ // (We can store scanlines which are already downscaled because our
+ // downscaling filter is separable.)
+ mWindowCapacity = mYFilter.MaxFilter();
+ mWindow.reset(new (fallible) uint8_t*[mWindowCapacity]);
+ if (MOZ_UNLIKELY(!mWindow)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ // Allocate the "window" of recent rows that we keep in memory as input for
+ // the downscaling code. We intentionally iterate through the entire array
+ // even if an allocation fails, to ensure that all the pointers in it are
+ // either valid or nullptr. That in turn ensures that ReleaseWindow() can
+ // clean up correctly.
+ bool anyAllocationFailed = false;
+ const size_t windowRowSizeInBytes = PaddedWidthInBytes(outputSize.width);
+ for (int32_t i = 0; i < mWindowCapacity; ++i) {
+ mWindow[i] = new (fallible) uint8_t[windowRowSizeInBytes];
+ anyAllocationFailed = anyAllocationFailed || mWindow[i] == nullptr;
+ }
+
+ if (MOZ_UNLIKELY(anyAllocationFailed)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ ConfigureFilter(mInputSize, sizeof(uint32_t));
+ return NS_OK;
+ }
+
+ Maybe<SurfaceInvalidRect> TakeInvalidRect() override {
+ Maybe<SurfaceInvalidRect> invalidRect = mNext.TakeInvalidRect();
+
+ if (invalidRect) {
+ // Compute the input space invalid rect by scaling.
+ invalidRect->mInputSpaceRect.ScaleRoundOut(mScale.xScale, mScale.yScale);
+ }
+
+ return invalidRect;
+ }
+
+ protected:
+ uint8_t* DoResetToFirstRow() override {
+ mNext.ResetToFirstRow();
+
+ mInputRow = 0;
+ mOutputRow = 0;
+ mRowsInWindow = 0;
+
+ return GetRowPointer();
+ }
+
+ uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
+ if (mInputRow >= mInputSize.height) {
+ NS_WARNING("Advancing DownscalingFilter past the end of the input");
+ return nullptr;
+ }
+
+ if (mOutputRow >= mNext.InputSize().height) {
+ NS_WARNING("Advancing DownscalingFilter past the end of the output");
+ return nullptr;
+ }
+
+ int32_t filterOffset = 0;
+ int32_t filterLength = 0;
+ mYFilter.GetFilterOffsetAndLength(mOutputRow, &filterOffset, &filterLength);
+
+ int32_t inputRowToRead = filterOffset + mRowsInWindow;
+ MOZ_ASSERT(mInputRow <= inputRowToRead, "Reading past end of input");
+ if (mInputRow == inputRowToRead) {
+ MOZ_RELEASE_ASSERT(mRowsInWindow < mWindowCapacity,
+ "Need more rows than capacity!");
+ mXFilter.ConvolveHorizontally(aInputRow, mWindow[mRowsInWindow++],
+ mHasAlpha);
+ }
+
+ MOZ_ASSERT(mOutputRow < mNext.InputSize().height,
+ "Writing past end of output");
+
+ while (mRowsInWindow >= filterLength) {
+ DownscaleInputRow();
+
+ if (mOutputRow == mNext.InputSize().height) {
+ break; // We're done.
+ }
+
+ mYFilter.GetFilterOffsetAndLength(mOutputRow, &filterOffset,
+ &filterLength);
+ }
+
+ mInputRow++;
+
+ return mInputRow < mInputSize.height ? GetRowPointer() : nullptr;
+ }
+
+ uint8_t* DoAdvanceRow() override {
+ return DoAdvanceRowFromBuffer(mRowBuffer.get());
+ }
+
+ private:
+ uint8_t* GetRowPointer() const { return mRowBuffer.get(); }
+
+ static size_t PaddedWidthInBytes(size_t aLogicalWidth) {
+ // Convert from width in BGRA/BGRX pixels to width in bytes, padding
+ // to handle overreads by the SIMD code inside Skia.
+ return gfx::ConvolutionFilter::PadBytesForSIMD(aLogicalWidth *
+ sizeof(uint32_t));
+ }
+
+ void DownscaleInputRow() {
+ MOZ_ASSERT(mOutputRow < mNext.InputSize().height,
+ "Writing past end of output");
+
+ int32_t filterOffset = 0;
+ int32_t filterLength = 0;
+ mYFilter.GetFilterOffsetAndLength(mOutputRow, &filterOffset, &filterLength);
+
+ mNext.template WriteUnsafeComputedRow<uint32_t>([&](uint32_t* aRow,
+ uint32_t aLength) {
+ mYFilter.ConvolveVertically(mWindow.get(),
+ reinterpret_cast<uint8_t*>(aRow), mOutputRow,
+ mXFilter.NumValues(), mHasAlpha);
+ });
+
+ mOutputRow++;
+
+ if (mOutputRow == mNext.InputSize().height) {
+ return; // We're done.
+ }
+
+ int32_t newFilterOffset = 0;
+ int32_t newFilterLength = 0;
+ mYFilter.GetFilterOffsetAndLength(mOutputRow, &newFilterOffset,
+ &newFilterLength);
+
+ int diff = newFilterOffset - filterOffset;
+ MOZ_ASSERT(diff >= 0, "Moving backwards in the filter?");
+
+ // Shift the buffer. We're just moving pointers here, so this is cheap.
+ mRowsInWindow -= diff;
+ mRowsInWindow = std::min(std::max(mRowsInWindow, 0), mWindowCapacity);
+
+ // If we already have enough rows to satisfy the filter, there is no need
+ // to swap as we won't be writing more before the next convolution.
+ if (filterLength > mRowsInWindow) {
+ for (int32_t i = 0; i < mRowsInWindow; ++i) {
+ std::swap(mWindow[i], mWindow[filterLength - mRowsInWindow + i]);
+ }
+ }
+ }
+
+ void ReleaseWindow() {
+ if (!mWindow) {
+ return;
+ }
+
+ for (int32_t i = 0; i < mWindowCapacity; ++i) {
+ delete[] mWindow[i];
+ }
+
+ mWindow = nullptr;
+ mWindowCapacity = 0;
+ }
+
+ Next mNext; /// The next SurfaceFilter in the chain.
+
+ gfx::IntSize mInputSize; /// The size of the input image.
+ gfx::MatrixScalesDouble mScale; /// The scale factors in each dimension.
+ /// Computed from @mInputSize and
+ /// the next filter's input size.
+
+ UniquePtr<uint8_t[]> mRowBuffer; /// The buffer into which input is written.
+ UniquePtr<uint8_t*[]> mWindow; /// The last few rows which were written.
+
+ gfx::ConvolutionFilter mXFilter; /// The Lanczos filter in X.
+ gfx::ConvolutionFilter mYFilter; /// The Lanczos filter in Y.
+
+ int32_t mWindowCapacity; /// How many rows the window contains.
+
+ int32_t mRowsInWindow; /// How many rows we've buffered in the window.
+ int32_t mInputRow; /// The current row we're reading. (0-indexed)
+ int32_t mOutputRow; /// The current row we're writing. (0-indexed)
+
+ bool mHasAlpha; /// If true, the image has transparency.
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_DownscalingFilter_h
diff --git a/image/DynamicImage.cpp b/image/DynamicImage.cpp
new file mode 100644
index 0000000000..923e91d352
--- /dev/null
+++ b/image/DynamicImage.cpp
@@ -0,0 +1,298 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "DynamicImage.h"
+#include "gfxContext.h"
+#include "gfxPlatform.h"
+#include "gfxUtils.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Logging.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/SVGImageContext.h"
+#include "ImageRegion.h"
+#include "Orientation.h"
+#include "mozilla/image/Resolution.h"
+
+#include "mozilla/MemoryReporting.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+
+namespace mozilla::image {
+
+// Inherited methods from Image.
+
+already_AddRefed<ProgressTracker> DynamicImage::GetProgressTracker() {
+ return nullptr;
+}
+
+size_t DynamicImage::SizeOfSourceWithComputedFallback(
+ SizeOfState& aState) const {
+ return 0;
+}
+
+void DynamicImage::CollectSizeOfSurfaces(
+ nsTArray<SurfaceMemoryCounter>& aCounters,
+ MallocSizeOf aMallocSizeOf) const {
+ // We can't report anything useful because gfxDrawable doesn't expose this
+ // information.
+}
+
+void DynamicImage::IncrementAnimationConsumers() {}
+
+void DynamicImage::DecrementAnimationConsumers() {}
+
+#ifdef DEBUG
+uint32_t DynamicImage::GetAnimationConsumers() { return 0; }
+#endif
+
+nsresult DynamicImage::OnImageDataAvailable(nsIRequest* aRequest,
+ nsIInputStream* aInStr,
+ uint64_t aSourceOffset,
+ uint32_t aCount) {
+ return NS_OK;
+}
+
+nsresult DynamicImage::OnImageDataComplete(nsIRequest* aRequest,
+ nsresult aStatus, bool aLastPart) {
+ return NS_OK;
+}
+
+void DynamicImage::OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) {}
+
+void DynamicImage::SetInnerWindowID(uint64_t aInnerWindowId) {}
+
+uint64_t DynamicImage::InnerWindowID() const { return 0; }
+
+bool DynamicImage::HasError() { return !mDrawable; }
+
+void DynamicImage::SetHasError() {}
+
+nsIURI* DynamicImage::GetURI() const { return nullptr; }
+
+// Methods inherited from XPCOM interfaces.
+
+NS_IMPL_ISUPPORTS(DynamicImage, imgIContainer)
+
+NS_IMETHODIMP
+DynamicImage::GetWidth(int32_t* aWidth) {
+ *aWidth = mDrawable->Size().width;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DynamicImage::GetHeight(int32_t* aHeight) {
+ *aHeight = mDrawable->Size().height;
+ return NS_OK;
+}
+
+void DynamicImage::MediaFeatureValuesChangedAllDocuments(
+ const mozilla::MediaFeatureChange& aChange) {}
+
+nsresult DynamicImage::GetNativeSizes(nsTArray<IntSize>&) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+size_t DynamicImage::GetNativeSizesLength() { return 0; }
+
+NS_IMETHODIMP
+DynamicImage::GetIntrinsicSize(nsSize* aSize) {
+ IntSize intSize(mDrawable->Size());
+ *aSize = nsSize(intSize.width, intSize.height);
+ return NS_OK;
+}
+
+Maybe<AspectRatio> DynamicImage::GetIntrinsicRatio() {
+ auto size = mDrawable->Size();
+ return Some(AspectRatio::FromSize(size.width, size.height));
+}
+
+NS_IMETHODIMP_(Orientation)
+DynamicImage::GetOrientation() { return Orientation(); }
+
+NS_IMETHODIMP_(Resolution)
+DynamicImage::GetResolution() { return {}; }
+
+NS_IMETHODIMP
+DynamicImage::GetType(uint16_t* aType) {
+ *aType = imgIContainer::TYPE_RASTER;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DynamicImage::GetProviderId(uint32_t* aId) {
+ *aId = 0;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DynamicImage::GetAnimated(bool* aAnimated) {
+ *aAnimated = false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+DynamicImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) {
+ IntSize size(mDrawable->Size());
+ return GetFrameAtSize(IntSize(size.width, size.height), aWhichFrame, aFlags);
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+DynamicImage::GetFrameAtSize(const IntSize& aSize, uint32_t aWhichFrame,
+ uint32_t aFlags) {
+ RefPtr<DrawTarget> dt =
+ gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
+ aSize, SurfaceFormat::OS_RGBA);
+ if (!dt || !dt->IsValid()) {
+ gfxWarning()
+ << "DynamicImage::GetFrame failed in CreateOffscreenContentDrawTarget";
+ return nullptr;
+ }
+ gfxContext context(dt);
+
+ auto result = Draw(&context, aSize, ImageRegion::Create(aSize), aWhichFrame,
+ SamplingFilter::POINT, SVGImageContext(), aFlags, 1.0);
+
+ return result == ImgDrawResult::SUCCESS ? dt->Snapshot() : nullptr;
+}
+
+NS_IMETHODIMP_(bool)
+DynamicImage::WillDrawOpaqueNow() { return false; }
+
+NS_IMETHODIMP_(bool)
+DynamicImage::IsImageContainerAvailable(WindowRenderer* aRenderer,
+ uint32_t aFlags) {
+ return false;
+}
+
+NS_IMETHODIMP_(ImgDrawResult)
+DynamicImage::GetImageProvider(WindowRenderer* aRenderer,
+ const gfx::IntSize& aSize,
+ const SVGImageContext& aSVGContext,
+ const Maybe<ImageIntRegion>& aRegion,
+ uint32_t aFlags,
+ WebRenderImageProvider** aProvider) {
+ return ImgDrawResult::NOT_SUPPORTED;
+}
+
+NS_IMETHODIMP_(ImgDrawResult)
+DynamicImage::Draw(gfxContext* aContext, const nsIntSize& aSize,
+ const ImageRegion& aRegion, uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ const SVGImageContext& aSVGContext, uint32_t aFlags,
+ float aOpacity) {
+ MOZ_ASSERT(!aSize.IsEmpty(), "Unexpected empty size");
+
+ IntSize drawableSize(mDrawable->Size());
+
+ if (aSize == drawableSize) {
+ gfxUtils::DrawPixelSnapped(aContext, mDrawable, SizeDouble(drawableSize),
+ aRegion, SurfaceFormat::OS_RGBA, aSamplingFilter,
+ aOpacity);
+ return ImgDrawResult::SUCCESS;
+ }
+
+ MatrixScalesDouble scale(double(aSize.width) / drawableSize.width,
+ double(aSize.height) / drawableSize.height);
+
+ ImageRegion region(aRegion);
+ region.Scale(1.0 / scale.xScale, 1.0 / scale.yScale);
+
+ gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
+ aContext->Multiply(gfxMatrix::Scaling(scale));
+
+ gfxUtils::DrawPixelSnapped(aContext, mDrawable, SizeDouble(drawableSize),
+ region, SurfaceFormat::OS_RGBA, aSamplingFilter,
+ aOpacity);
+ return ImgDrawResult::SUCCESS;
+}
+
+NS_IMETHODIMP
+DynamicImage::StartDecoding(uint32_t aFlags, uint32_t aWhichFrame) {
+ return NS_OK;
+}
+
+bool DynamicImage::StartDecodingWithResult(uint32_t aFlags,
+ uint32_t aWhichFrame) {
+ return true;
+}
+
+bool DynamicImage::HasDecodedPixels() { return true; }
+
+imgIContainer::DecodeResult DynamicImage::RequestDecodeWithResult(
+ uint32_t aFlags, uint32_t aWhichFrame) {
+ return imgIContainer::DECODE_SURFACE_AVAILABLE;
+}
+
+NS_IMETHODIMP
+DynamicImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags,
+ uint32_t aWhichFrame) {
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DynamicImage::LockImage() { return NS_OK; }
+
+NS_IMETHODIMP
+DynamicImage::UnlockImage() { return NS_OK; }
+
+NS_IMETHODIMP
+DynamicImage::RequestDiscard() { return NS_OK; }
+
+NS_IMETHODIMP_(void)
+DynamicImage::RequestRefresh(const mozilla::TimeStamp& aTime) {}
+
+NS_IMETHODIMP
+DynamicImage::GetAnimationMode(uint16_t* aAnimationMode) {
+ *aAnimationMode = kNormalAnimMode;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DynamicImage::SetAnimationMode(uint16_t aAnimationMode) { return NS_OK; }
+
+NS_IMETHODIMP
+DynamicImage::ResetAnimation() { return NS_OK; }
+
+NS_IMETHODIMP_(float)
+DynamicImage::GetFrameIndex(uint32_t aWhichFrame) { return 0; }
+
+NS_IMETHODIMP_(int32_t)
+DynamicImage::GetFirstFrameDelay() { return 0; }
+
+NS_IMETHODIMP_(void)
+DynamicImage::SetAnimationStartTime(const mozilla::TimeStamp& aTime) {}
+
+nsIntSize DynamicImage::OptimalImageSizeForDest(const gfxSize& aDest,
+ uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ uint32_t aFlags) {
+ IntSize size(mDrawable->Size());
+ return nsIntSize(size.width, size.height);
+}
+
+NS_IMETHODIMP_(nsIntRect)
+DynamicImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect) {
+ return aRect;
+}
+
+already_AddRefed<imgIContainer> DynamicImage::Unwrap() {
+ nsCOMPtr<imgIContainer> self(this);
+ return self.forget();
+}
+
+void DynamicImage::PropagateUseCounters(dom::Document*) {
+ // No use counters.
+}
+
+nsresult DynamicImage::GetHotspotX(int32_t* aX) {
+ return Image::GetHotspotX(aX);
+}
+
+nsresult DynamicImage::GetHotspotY(int32_t* aY) {
+ return Image::GetHotspotY(aY);
+}
+
+} // namespace mozilla::image
diff --git a/image/DynamicImage.h b/image/DynamicImage.h
new file mode 100644
index 0000000000..2b8a833958
--- /dev/null
+++ b/image/DynamicImage.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_DynamicImage_h
+#define mozilla_image_DynamicImage_h
+
+#include "mozilla/MemoryReporting.h"
+#include "gfxDrawable.h"
+#include "Image.h"
+
+namespace mozilla {
+namespace image {
+
+/**
+ * An Image that is dynamically created. The content of the image is provided by
+ * a gfxDrawable. It's anticipated that most uses of DynamicImage will be
+ * ephemeral.
+ */
+class DynamicImage : public Image {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_IMGICONTAINER
+
+ explicit DynamicImage(gfxDrawable* aDrawable) : mDrawable(aDrawable) {
+ MOZ_ASSERT(aDrawable, "Must have a gfxDrawable to wrap");
+ }
+
+ // Inherited methods from Image.
+ virtual already_AddRefed<ProgressTracker> GetProgressTracker() override;
+ virtual size_t SizeOfSourceWithComputedFallback(
+ SizeOfState& aState) const override;
+ virtual void CollectSizeOfSurfaces(nsTArray<SurfaceMemoryCounter>& aCounters,
+ MallocSizeOf aMallocSizeOf) const override;
+
+ virtual void IncrementAnimationConsumers() override;
+ virtual void DecrementAnimationConsumers() override;
+#ifdef DEBUG
+ virtual uint32_t GetAnimationConsumers() override;
+#endif
+
+ virtual nsresult OnImageDataAvailable(nsIRequest* aRequest,
+ nsIInputStream* aInStr,
+ uint64_t aSourceOffset,
+ uint32_t aCount) override;
+ virtual nsresult OnImageDataComplete(nsIRequest* aRequest, nsresult aStatus,
+ bool aLastPart) override;
+
+ virtual void OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) override;
+
+ virtual void SetInnerWindowID(uint64_t aInnerWindowId) override;
+ virtual uint64_t InnerWindowID() const override;
+
+ virtual bool HasError() override;
+ virtual void SetHasError() override;
+
+ nsIURI* GetURI() const override;
+
+ private:
+ virtual ~DynamicImage() {}
+
+ RefPtr<gfxDrawable> mDrawable;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_DynamicImage_h
diff --git a/image/FrameAnimator.cpp b/image/FrameAnimator.cpp
new file mode 100644
index 0000000000..f21877d81a
--- /dev/null
+++ b/image/FrameAnimator.cpp
@@ -0,0 +1,519 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "FrameAnimator.h"
+
+#include <utility>
+
+#include "LookupResult.h"
+#include "RasterImage.h"
+#include "imgIContainer.h"
+#include "mozilla/CheckedInt.h"
+#include "mozilla/ProfilerLabels.h"
+#include "mozilla/StaticPrefs_image.h"
+
+namespace mozilla {
+
+using namespace gfx;
+
+namespace image {
+
+///////////////////////////////////////////////////////////////////////////////
+// AnimationState implementation.
+///////////////////////////////////////////////////////////////////////////////
+
+const gfx::IntRect AnimationState::UpdateState(
+ RasterImage* aImage, const gfx::IntSize& aSize,
+ bool aAllowInvalidation /* = true */) {
+ LookupResult result = SurfaceCache::Lookup(
+ ImageKey(aImage),
+ RasterSurfaceKey(aSize, DefaultSurfaceFlags(), PlaybackType::eAnimated),
+ /* aMarkUsed = */ false);
+
+ return UpdateStateInternal(result, aSize, aAllowInvalidation);
+}
+
+const gfx::IntRect AnimationState::UpdateStateInternal(
+ LookupResult& aResult, const gfx::IntSize& aSize,
+ bool aAllowInvalidation /* = true */) {
+ // Update mDiscarded and mIsCurrentlyDecoded.
+ if (aResult.Type() == MatchType::NOT_FOUND) {
+ // no frames, we've either been discarded, or never been decoded before.
+ mDiscarded = mHasBeenDecoded;
+ mIsCurrentlyDecoded = false;
+ } else if (aResult.Type() == MatchType::PENDING) {
+ // no frames yet, but a decoder is or will be working on it.
+ mDiscarded = false;
+ mIsCurrentlyDecoded = false;
+ mHasRequestedDecode = true;
+ } else {
+ MOZ_ASSERT(aResult.Type() == MatchType::EXACT);
+ mDiscarded = false;
+ mHasRequestedDecode = true;
+
+ // If we can seek to the current animation frame we consider it decoded.
+ // Animated images are never fully decoded unless very short.
+ // Note that we use GetFrame instead of Seek here. The difference is that
+ // Seek eventually calls AnimationFrameBuffer::Get with aForDisplay == true,
+ // whereas GetFrame calls AnimationFrameBuffer::Get with aForDisplay ==
+ // false. The aForDisplay can change whether those functions succeed or not
+ // (only for the first frame). Since this is not for display we want to pass
+ // aForDisplay == false, but also for consistency with
+ // RequestRefresh/AdvanceFrame, because we want our state to be in sync with
+ // those functions. The user of Seek (GetCompositedFrame) doesn't need to be
+ // in sync with our state.
+ RefPtr<imgFrame> currentFrame =
+ bool(aResult.Surface())
+ ? aResult.Surface().GetFrame(mCurrentAnimationFrameIndex)
+ : nullptr;
+ mIsCurrentlyDecoded = !!currentFrame;
+ }
+
+ gfx::IntRect ret;
+
+ if (aAllowInvalidation) {
+ // Update the value of mCompositedFrameInvalid.
+ if (mIsCurrentlyDecoded) {
+ // It is safe to clear mCompositedFrameInvalid safe to do for images that
+ // are fully decoded but aren't finished animating because before we paint
+ // the refresh driver will call into us to advance to the correct frame,
+ // and that will succeed because we have all the frames.
+ if (mCompositedFrameInvalid) {
+ // Invalidate if we are marking the composited frame valid.
+ ret.SizeTo(aSize);
+ }
+ mCompositedFrameInvalid = false;
+ } else {
+ if (mHasRequestedDecode) {
+ MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable_AtStartup());
+ mCompositedFrameInvalid = true;
+ }
+ }
+ // Otherwise don't change the value of mCompositedFrameInvalid, it will be
+ // updated by RequestRefresh.
+ }
+
+ return ret;
+}
+
+void AnimationState::NotifyDecodeComplete() { mHasBeenDecoded = true; }
+
+void AnimationState::ResetAnimation() { mCurrentAnimationFrameIndex = 0; }
+
+void AnimationState::SetAnimationMode(uint16_t aAnimationMode) {
+ mAnimationMode = aAnimationMode;
+}
+
+void AnimationState::UpdateKnownFrameCount(uint32_t aFrameCount) {
+ if (aFrameCount <= mFrameCount) {
+ // Nothing to do. Since we can redecode animated images, we may see the same
+ // sequence of updates replayed again, so seeing a smaller frame count than
+ // what we already know about doesn't indicate an error.
+ return;
+ }
+
+ MOZ_ASSERT(!mHasBeenDecoded, "Adding new frames after decoding is finished?");
+ MOZ_ASSERT(aFrameCount <= mFrameCount + 1, "Skipped a frame?");
+
+ mFrameCount = aFrameCount;
+}
+
+Maybe<uint32_t> AnimationState::FrameCount() const {
+ return mHasBeenDecoded ? Some(mFrameCount) : Nothing();
+}
+
+void AnimationState::SetFirstFrameRefreshArea(const IntRect& aRefreshArea) {
+ mFirstFrameRefreshArea = aRefreshArea;
+}
+
+void AnimationState::InitAnimationFrameTimeIfNecessary() {
+ if (mCurrentAnimationFrameTime.IsNull()) {
+ mCurrentAnimationFrameTime = TimeStamp::Now();
+ }
+}
+
+void AnimationState::SetAnimationFrameTime(const TimeStamp& aTime) {
+ mCurrentAnimationFrameTime = aTime;
+}
+
+bool AnimationState::MaybeAdvanceAnimationFrameTime(const TimeStamp& aTime) {
+ if (!StaticPrefs::image_animated_resume_from_last_displayed() ||
+ mCurrentAnimationFrameTime >= aTime) {
+ return false;
+ }
+
+ // We are configured to stop an animation when it is out of view, and restart
+ // it from the same point when it comes back into view. The same applies if it
+ // was discarded while out of view.
+ mCurrentAnimationFrameTime = aTime;
+ return true;
+}
+
+uint32_t AnimationState::GetCurrentAnimationFrameIndex() const {
+ return mCurrentAnimationFrameIndex;
+}
+
+FrameTimeout AnimationState::LoopLength() const {
+ // If we don't know the loop length yet, we have to treat it as infinite.
+ if (!mLoopLength) {
+ return FrameTimeout::Forever();
+ }
+
+ MOZ_ASSERT(mHasBeenDecoded,
+ "We know the loop length but decoding isn't done?");
+
+ // If we're not looping, a single loop time has no meaning.
+ if (mAnimationMode != imgIContainer::kNormalAnimMode) {
+ return FrameTimeout::Forever();
+ }
+
+ return *mLoopLength;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// FrameAnimator implementation.
+///////////////////////////////////////////////////////////////////////////////
+
+TimeStamp FrameAnimator::GetCurrentImgFrameEndTime(
+ AnimationState& aState, FrameTimeout aCurrentTimeout) const {
+ if (aCurrentTimeout == FrameTimeout::Forever()) {
+ // We need to return a sentinel value in this case, because our logic
+ // doesn't work correctly if we have an infinitely long timeout. We use one
+ // year in the future as the sentinel because it works with the loop in
+ // RequestRefresh() below.
+ // XXX(seth): It'd be preferable to make our logic work correctly with
+ // infinitely long timeouts.
+ return TimeStamp::NowLoRes() + TimeDuration::FromMilliseconds(31536000.0);
+ }
+
+ TimeDuration durationOfTimeout =
+ TimeDuration::FromMilliseconds(double(aCurrentTimeout.AsMilliseconds()));
+ return aState.mCurrentAnimationFrameTime + durationOfTimeout;
+}
+
+RefreshResult FrameAnimator::AdvanceFrame(AnimationState& aState,
+ DrawableSurface& aFrames,
+ RefPtr<imgFrame>& aCurrentFrame,
+ TimeStamp aTime) {
+ AUTO_PROFILER_LABEL("FrameAnimator::AdvanceFrame", GRAPHICS);
+
+ RefreshResult ret;
+
+ // Determine what the next frame is, taking into account looping.
+ uint32_t currentFrameIndex = aState.mCurrentAnimationFrameIndex;
+ uint32_t nextFrameIndex = currentFrameIndex + 1;
+
+ // Check if we're at the end of the loop. (FrameCount() returns Nothing() if
+ // we don't know the total count yet.)
+ if (aState.FrameCount() == Some(nextFrameIndex)) {
+ // If we are not looping forever, initialize the loop counter
+ if (aState.mLoopRemainingCount < 0 && aState.LoopCount() >= 0) {
+ aState.mLoopRemainingCount = aState.LoopCount();
+ }
+
+ // If animation mode is "loop once", or we're at end of loop counter,
+ // it's time to stop animating.
+ if (aState.mAnimationMode == imgIContainer::kLoopOnceAnimMode ||
+ aState.mLoopRemainingCount == 0) {
+ ret.mAnimationFinished = true;
+ }
+
+ nextFrameIndex = 0;
+
+ if (aState.mLoopRemainingCount > 0) {
+ aState.mLoopRemainingCount--;
+ }
+
+ // If we're done, exit early.
+ if (ret.mAnimationFinished) {
+ return ret;
+ }
+ }
+
+ if (nextFrameIndex >= aState.KnownFrameCount()) {
+ // We've already advanced to the last decoded frame, nothing more we can do.
+ // We're blocked by network/decoding from displaying the animation at the
+ // rate specified, so that means the frame we are displaying (the latest
+ // available) is the frame we want to be displaying at this time. So we
+ // update the current animation time. If we didn't update the current
+ // animation time then it could lag behind, which would indicate that we are
+ // behind in the animation and should try to catch up. When we are done
+ // decoding (and thus can loop around back to the start of the animation) we
+ // would then jump to a random point in the animation to try to catch up.
+ // But we were never behind in the animation.
+ aState.mCurrentAnimationFrameTime = aTime;
+ return ret;
+ }
+
+ // There can be frames in the surface cache with index >= KnownFrameCount()
+ // which GetRawFrame() can access because an async decoder has decoded them,
+ // but which AnimationState doesn't know about yet because we haven't received
+ // the appropriate notification on the main thread. Make sure we stay in sync
+ // with AnimationState.
+ MOZ_ASSERT(nextFrameIndex < aState.KnownFrameCount());
+ RefPtr<imgFrame> nextFrame = aFrames.GetFrame(nextFrameIndex);
+
+ // We should always check to see if we have the next frame even if we have
+ // previously finished decoding. If we needed to redecode (e.g. due to a draw
+ // failure) we would have discarded all the old frames and may not yet have
+ // the new ones. DrawableSurface::RawAccessRef promises to only return
+ // finished frames.
+ if (!nextFrame) {
+ // Uh oh, the frame we want to show is currently being decoded (partial).
+ // Similar to the above case, we could be blocked by network or decoding,
+ // and so we should advance our current time rather than risk jumping
+ // through the animation. We will wait until the next refresh driver tick
+ // and try again.
+ aState.mCurrentAnimationFrameTime = aTime;
+ return ret;
+ }
+
+ if (nextFrame->GetTimeout() == FrameTimeout::Forever()) {
+ ret.mAnimationFinished = true;
+ }
+
+ if (nextFrameIndex == 0) {
+ ret.mDirtyRect = aState.FirstFrameRefreshArea();
+ } else {
+ ret.mDirtyRect = nextFrame->GetDirtyRect();
+ }
+
+ aState.mCurrentAnimationFrameTime =
+ GetCurrentImgFrameEndTime(aState, aCurrentFrame->GetTimeout());
+
+ // If we can get closer to the current time by a multiple of the image's loop
+ // time, we should. We can only do this if we're done decoding; otherwise, we
+ // don't know the full loop length, and LoopLength() will have to return
+ // FrameTimeout::Forever(). We also skip this for images with a finite loop
+ // count if we have initialized mLoopRemainingCount (it only gets initialized
+ // after one full loop).
+ FrameTimeout loopTime = aState.LoopLength();
+ if (loopTime != FrameTimeout::Forever() &&
+ (aState.LoopCount() < 0 || aState.mLoopRemainingCount >= 0)) {
+ TimeDuration delay = aTime - aState.mCurrentAnimationFrameTime;
+ if (delay.ToMilliseconds() > loopTime.AsMilliseconds()) {
+ // Explicitly use integer division to get the floor of the number of
+ // loops.
+ uint64_t loops = static_cast<uint64_t>(delay.ToMilliseconds()) /
+ loopTime.AsMilliseconds();
+
+ // If we have a finite loop count limit the number of loops we advance.
+ if (aState.mLoopRemainingCount >= 0) {
+ MOZ_ASSERT(aState.LoopCount() >= 0);
+ loops =
+ std::min(loops, CheckedUint64(aState.mLoopRemainingCount).value());
+ }
+
+ aState.mCurrentAnimationFrameTime +=
+ TimeDuration::FromMilliseconds(loops * loopTime.AsMilliseconds());
+
+ if (aState.mLoopRemainingCount >= 0) {
+ MOZ_ASSERT(loops <= CheckedUint64(aState.mLoopRemainingCount).value());
+ aState.mLoopRemainingCount -= CheckedInt32(loops).value();
+ }
+ }
+ }
+
+ // Set currentAnimationFrameIndex at the last possible moment
+ aState.mCurrentAnimationFrameIndex = nextFrameIndex;
+ aCurrentFrame = std::move(nextFrame);
+ aFrames.Advance(nextFrameIndex);
+
+ // If we're here, we successfully advanced the frame.
+ ret.mFrameAdvanced = true;
+
+ return ret;
+}
+
+void FrameAnimator::ResetAnimation(AnimationState& aState) {
+ aState.ResetAnimation();
+
+ // Our surface provider is synchronized to our state, so we need to reset its
+ // state as well, if we still have one.
+ SurfaceCache::ResetAnimation(
+ ImageKey(mImage),
+ RasterSurfaceKey(mSize, DefaultSurfaceFlags(), PlaybackType::eAnimated));
+
+ // Calling Reset on the surface of the animation can cause discarding surface
+ // providers to throw out all their frames so refresh our state.
+ OrientedIntRect rect =
+ OrientedIntRect::FromUnknownRect(aState.UpdateState(mImage, mSize));
+
+ if (!rect.IsEmpty()) {
+ nsCOMPtr<nsIEventTarget> eventTarget = do_GetMainThread();
+ RefPtr<RasterImage> image = mImage;
+ nsCOMPtr<nsIRunnable> ev = NS_NewRunnableFunction(
+ "FrameAnimator::ResetAnimation",
+ [=]() -> void { image->NotifyProgress(NoProgress, rect); });
+ eventTarget->Dispatch(ev.forget(), NS_DISPATCH_NORMAL);
+ }
+}
+
+RefreshResult FrameAnimator::RequestRefresh(AnimationState& aState,
+ const TimeStamp& aTime) {
+ // By default, an empty RefreshResult.
+ RefreshResult ret;
+
+ if (aState.IsDiscarded()) {
+ aState.MaybeAdvanceAnimationFrameTime(aTime);
+ return ret;
+ }
+
+ // Get the animation frames once now, and pass them down to callees because
+ // the surface could be discarded at anytime on a different thread. This is
+ // must easier to reason about then trying to write code that is safe to
+ // having the surface disappear at anytime.
+ LookupResult result = SurfaceCache::Lookup(
+ ImageKey(mImage),
+ RasterSurfaceKey(mSize, DefaultSurfaceFlags(), PlaybackType::eAnimated),
+ /* aMarkUsed = */ true);
+
+ ret.mDirtyRect = aState.UpdateStateInternal(result, mSize);
+ if (aState.IsDiscarded() || !result) {
+ aState.MaybeAdvanceAnimationFrameTime(aTime);
+ return ret;
+ }
+
+ RefPtr<imgFrame> currentFrame =
+ result.Surface().GetFrame(aState.mCurrentAnimationFrameIndex);
+
+ // only advance the frame if the current time is greater than or
+ // equal to the current frame's end time.
+ if (!currentFrame) {
+ MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable_AtStartup());
+ MOZ_ASSERT(aState.GetHasRequestedDecode() &&
+ !aState.GetIsCurrentlyDecoded());
+ MOZ_ASSERT(aState.mCompositedFrameInvalid);
+ // Nothing we can do but wait for our previous current frame to be decoded
+ // again so we can determine what to do next.
+ aState.MaybeAdvanceAnimationFrameTime(aTime);
+ return ret;
+ }
+
+ TimeStamp currentFrameEndTime =
+ GetCurrentImgFrameEndTime(aState, currentFrame->GetTimeout());
+
+ // If nothing has accessed the composited frame since the last time we
+ // advanced, then there is no point in continuing to advance the animation.
+ // This has the effect of freezing the animation while not in view.
+ if (!result.Surface().MayAdvance() &&
+ aState.MaybeAdvanceAnimationFrameTime(aTime)) {
+ return ret;
+ }
+
+ while (currentFrameEndTime <= aTime) {
+ TimeStamp oldFrameEndTime = currentFrameEndTime;
+
+ RefreshResult frameRes =
+ AdvanceFrame(aState, result.Surface(), currentFrame, aTime);
+
+ // Accumulate our result for returning to callers.
+ ret.Accumulate(frameRes);
+
+ // currentFrame was updated by AdvanceFrame so it is still current.
+ currentFrameEndTime =
+ GetCurrentImgFrameEndTime(aState, currentFrame->GetTimeout());
+
+ // If we didn't advance a frame, and our frame end time didn't change,
+ // then we need to break out of this loop & wait for the frame(s)
+ // to finish downloading.
+ if (!frameRes.mFrameAdvanced && currentFrameEndTime == oldFrameEndTime) {
+ break;
+ }
+ }
+
+ // We should only mark the composited frame as valid and reset the dirty rect
+ // if we advanced (meaning the next frame was actually produced somehow), the
+ // composited frame was previously invalid (so we may need to repaint
+ // everything) and either the frame index is valid (to know we were doing
+ // blending on the main thread, instead of on the decoder threads in advance),
+ // or the current frame is a full frame (blends off the main thread).
+ //
+ // If for some reason we forget to reset aState.mCompositedFrameInvalid, then
+ // GetCompositedFrame will fail, even if we have all the data available for
+ // display.
+ if (currentFrameEndTime > aTime && aState.mCompositedFrameInvalid) {
+ aState.mCompositedFrameInvalid = false;
+ ret.mDirtyRect = IntRect(IntPoint(0, 0), mSize);
+ }
+
+ MOZ_ASSERT(!aState.mIsCurrentlyDecoded || !aState.mCompositedFrameInvalid);
+
+ return ret;
+}
+
+LookupResult FrameAnimator::GetCompositedFrame(AnimationState& aState,
+ bool aMarkUsed) {
+ LookupResult result = SurfaceCache::Lookup(
+ ImageKey(mImage),
+ RasterSurfaceKey(mSize, DefaultSurfaceFlags(), PlaybackType::eAnimated),
+ aMarkUsed);
+
+ if (result) {
+ // If we are getting the frame directly (e.g. through tests or canvas), we
+ // need to ensure the animation is marked to allow advancing to the next
+ // frame.
+ result.Surface().MarkMayAdvance();
+ }
+
+ if (aState.mCompositedFrameInvalid) {
+ MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable_AtStartup());
+ MOZ_ASSERT(aState.GetHasRequestedDecode());
+ MOZ_ASSERT(!aState.GetIsCurrentlyDecoded());
+
+ if (result.Type() == MatchType::EXACT) {
+ // If our composited frame is marked as invalid but our frames are in the
+ // surface cache we might just have not updated our internal state yet.
+ // This can happen if the image is not in a document so that
+ // RequestRefresh is not getting called to advance the frame.
+ // RequestRefresh would result in our composited frame getting marked as
+ // valid either at the end of RequestRefresh when we are able to advance
+ // to the current time or if advancing frames eventually causes us to
+ // decode all of the frames of the image resulting in DecodeComplete
+ // getting called which calls UpdateState. The reason we care about this
+ // is that img.decode promises won't resolve until GetCompositedFrame
+ // returns a frame.
+ OrientedIntRect rect = OrientedIntRect::FromUnknownRect(
+ aState.UpdateStateInternal(result, mSize));
+
+ if (!rect.IsEmpty()) {
+ nsCOMPtr<nsIEventTarget> eventTarget = do_GetMainThread();
+ RefPtr<RasterImage> image = mImage;
+ nsCOMPtr<nsIRunnable> ev = NS_NewRunnableFunction(
+ "FrameAnimator::GetCompositedFrame",
+ [=]() -> void { image->NotifyProgress(NoProgress, rect); });
+ eventTarget->Dispatch(ev.forget(), NS_DISPATCH_NORMAL);
+ }
+ }
+
+ // If it's still invalid we have to return.
+ if (aState.mCompositedFrameInvalid) {
+ if (result.Type() == MatchType::NOT_FOUND) {
+ return result;
+ }
+ return LookupResult(MatchType::PENDING);
+ }
+ }
+
+ // Otherwise return the raw frame. DoBlend is required to ensure that we only
+ // hit this case if the frame is not paletted and doesn't require compositing.
+ if (!result) {
+ return result;
+ }
+
+ // Seek to the appropriate frame. If seeking fails, it means that we couldn't
+ // get the frame we're looking for; treat this as if the lookup failed.
+ if (NS_FAILED(result.Surface().Seek(aState.mCurrentAnimationFrameIndex))) {
+ if (result.Type() == MatchType::NOT_FOUND) {
+ return result;
+ }
+ return LookupResult(MatchType::PENDING);
+ }
+
+ return result;
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/FrameAnimator.h b/image/FrameAnimator.h
new file mode 100644
index 0000000000..40538a3beb
--- /dev/null
+++ b/image/FrameAnimator.h
@@ -0,0 +1,343 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_FrameAnimator_h
+#define mozilla_image_FrameAnimator_h
+
+#include "mozilla/Maybe.h"
+#include "mozilla/StaticPrefs_image.h"
+#include "mozilla/TimeStamp.h"
+#include "gfxTypes.h"
+#include "imgFrame.h"
+#include "nsCOMPtr.h"
+#include "nsRect.h"
+#include "SurfaceCache.h"
+
+namespace mozilla {
+namespace image {
+
+class RasterImage;
+class DrawableSurface;
+
+class AnimationState {
+ public:
+ explicit AnimationState(uint16_t aAnimationMode)
+ : mFrameCount(0),
+ mCurrentAnimationFrameIndex(0),
+ mLoopRemainingCount(-1),
+ mLoopCount(-1),
+ mFirstFrameTimeout(FrameTimeout::FromRawMilliseconds(0)),
+ mAnimationMode(aAnimationMode),
+ mHasBeenDecoded(false),
+ mHasRequestedDecode(false),
+ mIsCurrentlyDecoded(false),
+ mCompositedFrameInvalid(false),
+ mDiscarded(false) {}
+
+ /**
+ * Call this whenever a decode completes, a decode starts, or the image is
+ * discarded. It will update the internal state. Specifically mDiscarded,
+ * mCompositedFrameInvalid, and mIsCurrentlyDecoded. If aAllowInvalidation
+ * is true then returns a rect to invalidate.
+ */
+ const gfx::IntRect UpdateState(RasterImage* aImage, const gfx::IntSize& aSize,
+ bool aAllowInvalidation = true);
+
+ private:
+ const gfx::IntRect UpdateStateInternal(LookupResult& aResult,
+ const gfx::IntSize& aSize,
+ bool aAllowInvalidation = true);
+
+ public:
+ /**
+ * Call when a decode of this image has been completed.
+ */
+ void NotifyDecodeComplete();
+
+ /**
+ * Returns true if this image has been fully decoded before.
+ */
+ bool GetHasBeenDecoded() { return mHasBeenDecoded; }
+
+ /**
+ * Returns true if this image has ever requested a decode before.
+ */
+ bool GetHasRequestedDecode() { return mHasRequestedDecode; }
+
+ /**
+ * Returns true if this image has been discarded and a decoded has not yet
+ * been created to redecode it.
+ */
+ bool IsDiscarded() { return mDiscarded; }
+
+ /**
+ * Sets the composited frame as valid or invalid.
+ */
+ void SetCompositedFrameInvalid(bool aInvalid) {
+ MOZ_ASSERT(!aInvalid ||
+ StaticPrefs::image_mem_animated_discardable_AtStartup());
+ mCompositedFrameInvalid = aInvalid;
+ }
+
+ /**
+ * Returns whether the composited frame is valid to draw to the screen.
+ */
+ bool GetCompositedFrameInvalid() { return mCompositedFrameInvalid; }
+
+ /**
+ * Returns whether the image is currently full decoded..
+ */
+ bool GetIsCurrentlyDecoded() { return mIsCurrentlyDecoded; }
+
+ /**
+ * Call when you need to re-start animating. Ensures we start from the first
+ * frame.
+ */
+ void ResetAnimation();
+
+ /**
+ * The animation mode of the image.
+ *
+ * Constants defined in imgIContainer.idl.
+ */
+ void SetAnimationMode(uint16_t aAnimationMode);
+
+ /// Update the number of frames of animation this image is known to have.
+ void UpdateKnownFrameCount(uint32_t aFrameCount);
+
+ /// @return the number of frames of animation we know about so far.
+ uint32_t KnownFrameCount() const { return mFrameCount; }
+
+ /// @return the number of frames this animation has, if we know for sure.
+ /// (In other words, if decoding is finished.) Otherwise, returns Nothing().
+ Maybe<uint32_t> FrameCount() const;
+
+ /**
+ * Get or set the area of the image to invalidate when we loop around to the
+ * first frame.
+ */
+ void SetFirstFrameRefreshArea(const gfx::IntRect& aRefreshArea);
+ gfx::IntRect FirstFrameRefreshArea() const { return mFirstFrameRefreshArea; }
+
+ /**
+ * If the animation frame time has not yet been set, set it to
+ * TimeStamp::Now().
+ */
+ void InitAnimationFrameTimeIfNecessary();
+
+ /**
+ * Set the animation frame time to @aTime.
+ */
+ void SetAnimationFrameTime(const TimeStamp& aTime);
+
+ /**
+ * Set the animation frame time to @aTime if we are configured to stop the
+ * animation when not visible and aTime is later than the current time.
+ * Returns true if the time was updated, else false.
+ */
+ bool MaybeAdvanceAnimationFrameTime(const TimeStamp& aTime);
+
+ /**
+ * The current frame we're on, from 0 to (numFrames - 1).
+ */
+ uint32_t GetCurrentAnimationFrameIndex() const;
+
+ /*
+ * Set number of times to loop the image.
+ * @note -1 means loop forever.
+ */
+ void SetLoopCount(int32_t aLoopCount) { mLoopCount = aLoopCount; }
+ int32_t LoopCount() const { return mLoopCount; }
+
+ /// Set the @aLength of a single loop through this image.
+ void SetLoopLength(FrameTimeout aLength) { mLoopLength = Some(aLength); }
+
+ /**
+ * @return the length of a single loop of this image. If this image is not
+ * finished decoding, is not animated, or it is animated but does not loop,
+ * returns FrameTimeout::Forever().
+ */
+ FrameTimeout LoopLength() const;
+
+ /*
+ * Get or set the timeout for the first frame. This is used to allow animation
+ * scheduling even before a full decode runs for this image.
+ */
+ void SetFirstFrameTimeout(FrameTimeout aTimeout) {
+ mFirstFrameTimeout = aTimeout;
+ }
+ FrameTimeout FirstFrameTimeout() const { return mFirstFrameTimeout; }
+
+ private:
+ friend class FrameAnimator;
+
+ //! Area of the first frame that needs to be redrawn on subsequent loops.
+ gfx::IntRect mFirstFrameRefreshArea;
+
+ //! the time that the animation advanced to the current frame
+ TimeStamp mCurrentAnimationFrameTime;
+
+ //! The number of frames of animation this image has.
+ uint32_t mFrameCount;
+
+ //! The current frame index we're on, in the range [0, mFrameCount).
+ uint32_t mCurrentAnimationFrameIndex;
+
+ //! number of loops remaining before animation stops (-1 no stop)
+ int32_t mLoopRemainingCount;
+
+ //! The total number of loops for the image.
+ int32_t mLoopCount;
+
+ //! The length of a single loop through this image.
+ Maybe<FrameTimeout> mLoopLength;
+
+ //! The timeout for the first frame of this image.
+ FrameTimeout mFirstFrameTimeout;
+
+ //! The animation mode of this image. Constants defined in imgIContainer.
+ uint16_t mAnimationMode;
+
+ /**
+ * The following four bools (mHasBeenDecoded, mIsCurrentlyDecoded,
+ * mCompositedFrameInvalid, mDiscarded) track the state of the image with
+ * regards to decoding. They all start out false, including mDiscarded,
+ * because we want to treat being discarded differently from "not yet decoded
+ * for the first time".
+ *
+ * (When we are decoding the image for the first time we want to show the
+ * image at the speed of data coming in from the network or the speed
+ * specified in the image file, whichever is slower. But when redecoding we
+ * want to show nothing until the frame for the current time has been
+ * decoded. The prevents the user from seeing the image "fast forward"
+ * to the expected spot.)
+ *
+ * When the image is decoded for the first time mHasBeenDecoded and
+ * mIsCurrentlyDecoded get set to true. When the image is discarded
+ * mIsCurrentlyDecoded gets set to false, and mCompositedFrameInvalid
+ * & mDiscarded get set to true. When we create a decoder to redecode the
+ * image mDiscarded gets set to false. mCompositedFrameInvalid gets set to
+ * false when we are able to advance to the frame that should be showing
+ * for the current time. mIsCurrentlyDecoded gets set to true when the
+ * redecode finishes.
+ */
+
+ //! Whether this image has been decoded at least once.
+ bool mHasBeenDecoded;
+
+ //! Whether this image has ever requested a decode.
+ bool mHasRequestedDecode;
+
+ //! Whether this image is currently fully decoded.
+ bool mIsCurrentlyDecoded;
+
+ //! Whether the composited frame is valid to draw to the screen, note that
+ //! the composited frame can exist and be filled with image data but not
+ //! valid to draw to the screen.
+ bool mCompositedFrameInvalid;
+
+ //! Whether this image is currently discarded. Only set to true after the
+ //! image has been decoded at least once.
+ bool mDiscarded;
+};
+
+/**
+ * RefreshResult is used to let callers know how the state of the animation
+ * changed during a call to FrameAnimator::RequestRefresh().
+ */
+struct RefreshResult {
+ RefreshResult() : mFrameAdvanced(false), mAnimationFinished(false) {}
+
+ /// Merges another RefreshResult's changes into this RefreshResult.
+ void Accumulate(const RefreshResult& aOther) {
+ mFrameAdvanced = mFrameAdvanced || aOther.mFrameAdvanced;
+ mAnimationFinished = mAnimationFinished || aOther.mAnimationFinished;
+ mDirtyRect = mDirtyRect.Union(aOther.mDirtyRect);
+ }
+
+ // The region of the image that has changed.
+ gfx::IntRect mDirtyRect;
+
+ // If true, we changed frames at least once. Note that, due to looping, we
+ // could still have ended up on the same frame!
+ bool mFrameAdvanced : 1;
+
+ // Whether the animation has finished playing.
+ bool mAnimationFinished : 1;
+};
+
+class FrameAnimator {
+ public:
+ FrameAnimator(RasterImage* aImage, const gfx::IntSize& aSize)
+ : mImage(aImage), mSize(aSize) {
+ MOZ_COUNT_CTOR(FrameAnimator);
+ }
+
+ MOZ_COUNTED_DTOR(FrameAnimator)
+
+ /**
+ * Call when you need to re-start animating. Ensures we start from the first
+ * frame.
+ */
+ void ResetAnimation(AnimationState& aState);
+
+ /**
+ * Re-evaluate what frame we're supposed to be on, and do whatever blending
+ * is necessary to get us to that frame.
+ *
+ * Returns the result of that blending, including whether the current frame
+ * changed and what the resulting dirty rectangle is.
+ */
+ RefreshResult RequestRefresh(AnimationState& aState, const TimeStamp& aTime);
+
+ /**
+ * Get the full frame for the current frame of the animation (it may or may
+ * not have required compositing). It may not be available because it hasn't
+ * been decoded yet, in which case we return an empty LookupResult.
+ */
+ LookupResult GetCompositedFrame(AnimationState& aState, bool aMarkUsed);
+
+ private: // methods
+ /**
+ * Advances the animation. Typically, this will advance a single frame, but it
+ * may advance multiple frames. This may happen if we have infrequently
+ * "ticking" refresh drivers (e.g. in background tabs), or extremely short-
+ * lived animation frames.
+ *
+ * @param aTime the time that the animation should advance to. This will
+ * typically be <= TimeStamp::Now().
+ *
+ * @param aCurrentFrame the currently displayed frame of the animation. If
+ * we advance, it will replace aCurrentFrame with the
+ * new current frame we advanced to.
+ *
+ * @returns a RefreshResult that shows whether the frame was successfully
+ * advanced, and its resulting dirty rect.
+ */
+ RefreshResult AdvanceFrame(AnimationState& aState, DrawableSurface& aFrames,
+ RefPtr<imgFrame>& aCurrentFrame, TimeStamp aTime);
+
+ /**
+ * Get the time the frame we're currently displaying is supposed to end.
+ *
+ * In the error case (like if the requested frame is not currently
+ * decoded), returns None().
+ */
+ TimeStamp GetCurrentImgFrameEndTime(AnimationState& aState,
+ FrameTimeout aCurrentTimeout) const;
+
+ private: // data
+ //! A weak pointer to our owning image.
+ RasterImage* mImage;
+
+ //! The intrinsic size of the image.
+ gfx::IntSize mSize;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_FrameAnimator_h
diff --git a/image/FrameTimeout.h b/image/FrameTimeout.h
new file mode 100644
index 0000000000..8cc38e203a
--- /dev/null
+++ b/image/FrameTimeout.h
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_FrameTimeout_h
+#define mozilla_image_FrameTimeout_h
+
+#include <stdint.h>
+#include "mozilla/Assertions.h"
+
+namespace mozilla {
+namespace image {
+
+/**
+ * FrameTimeout wraps a frame timeout value (measured in milliseconds) after
+ * first normalizing it. This normalization is necessary because some tools
+ * generate incorrect frame timeout values which we nevertheless have to
+ * support. For this reason, code that deals with frame timeouts should always
+ * use a FrameTimeout value rather than the raw value from the image header.
+ */
+struct FrameTimeout {
+ /**
+ * @return a FrameTimeout of zero. This should be used only for math
+ * involving FrameTimeout values. You can't obtain a zero FrameTimeout from
+ * FromRawMilliseconds().
+ */
+ static FrameTimeout Zero() { return FrameTimeout(0); }
+
+ /// @return an infinite FrameTimeout.
+ static FrameTimeout Forever() { return FrameTimeout(-1); }
+
+ /// @return a FrameTimeout obtained by normalizing a raw timeout value.
+ static FrameTimeout FromRawMilliseconds(int32_t aRawMilliseconds) {
+ // Normalize all infinite timeouts to the same value.
+ if (aRawMilliseconds < 0) {
+ return FrameTimeout::Forever();
+ }
+
+ // Very small timeout values are problematic for two reasons: we don't want
+ // to burn energy redrawing animated images extremely fast, and broken tools
+ // generate these values when they actually want a "default" value, so such
+ // images won't play back right without normalization. For some context,
+ // see bug 890743, bug 125137, bug 139677, and bug 207059. The historical
+ // behavior of IE and Opera was:
+ // IE 6/Win:
+ // 10 - 50ms is normalized to 100ms.
+ // >50ms is used unnormalized.
+ // Opera 7 final/Win:
+ // 10ms is normalized to 100ms.
+ // >10ms is used unnormalized.
+ if (aRawMilliseconds >= 0 && aRawMilliseconds <= 10) {
+ return FrameTimeout(100);
+ }
+
+ // The provided timeout value is OK as-is.
+ return FrameTimeout(aRawMilliseconds);
+ }
+
+ bool operator==(const FrameTimeout& aOther) const {
+ return mTimeout == aOther.mTimeout;
+ }
+
+ bool operator!=(const FrameTimeout& aOther) const {
+ return !(*this == aOther);
+ }
+
+ FrameTimeout operator+(const FrameTimeout& aOther) {
+ if (*this == Forever() || aOther == Forever()) {
+ return Forever();
+ }
+
+ return FrameTimeout(mTimeout + aOther.mTimeout);
+ }
+
+ FrameTimeout& operator+=(const FrameTimeout& aOther) {
+ *this = *this + aOther;
+ return *this;
+ }
+
+ /**
+ * @return this FrameTimeout's value in milliseconds. Illegal to call on a
+ * an infinite FrameTimeout value.
+ */
+ uint32_t AsMilliseconds() const {
+ if (*this == Forever()) {
+ MOZ_ASSERT_UNREACHABLE(
+ "Calling AsMilliseconds() on an infinite FrameTimeout");
+ return 100; // Fail to something sane.
+ }
+
+ return uint32_t(mTimeout);
+ }
+
+ /**
+ * @return this FrameTimeout value encoded so that non-negative values
+ * represent a timeout in milliseconds, and -1 represents an infinite
+ * timeout.
+ *
+ * XXX(seth): This is a backwards compatibility hack that should be removed.
+ */
+ int32_t AsEncodedValueDeprecated() const { return mTimeout; }
+
+ private:
+ explicit FrameTimeout(int32_t aTimeout) : mTimeout(aTimeout) {}
+
+ int32_t mTimeout;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_FrameTimeout_h
diff --git a/image/FrozenImage.cpp b/image/FrozenImage.cpp
new file mode 100644
index 0000000000..bb82aaedd6
--- /dev/null
+++ b/image/FrozenImage.cpp
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "FrozenImage.h"
+
+namespace mozilla {
+
+using namespace gfx;
+using layers::ImageContainer;
+
+namespace image {
+
+void FrozenImage::IncrementAnimationConsumers() {
+ // Do nothing. This will prevent animation from starting if there are no other
+ // instances of this image.
+}
+
+void FrozenImage::DecrementAnimationConsumers() {
+ // Do nothing.
+}
+
+NS_IMETHODIMP
+FrozenImage::GetAnimated(bool* aAnimated) {
+ bool dummy;
+ nsresult rv = InnerImage()->GetAnimated(&dummy);
+ if (NS_SUCCEEDED(rv)) {
+ *aAnimated = false;
+ }
+ return rv;
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+FrozenImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) {
+ return InnerImage()->GetFrame(FRAME_FIRST, aFlags);
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+FrozenImage::GetFrameAtSize(const IntSize& aSize, uint32_t aWhichFrame,
+ uint32_t aFlags) {
+ return InnerImage()->GetFrameAtSize(aSize, FRAME_FIRST, aFlags);
+}
+
+bool FrozenImage::IsNonAnimated() const {
+ // We usually don't create frozen images for non-animated images, but it might
+ // happen if we don't have enough data at the time of the creation to
+ // determine whether the image is actually animated.
+ bool animated = false;
+ return NS_SUCCEEDED(InnerImage()->GetAnimated(&animated)) && !animated;
+}
+
+NS_IMETHODIMP_(bool)
+FrozenImage::IsImageContainerAvailable(WindowRenderer* aRenderer,
+ uint32_t aFlags) {
+ if (IsNonAnimated()) {
+ return InnerImage()->IsImageContainerAvailable(aRenderer, aFlags);
+ }
+ return false;
+}
+
+NS_IMETHODIMP_(ImgDrawResult)
+FrozenImage::GetImageProvider(WindowRenderer* aRenderer,
+ const gfx::IntSize& aSize,
+ const SVGImageContext& aSVGContext,
+ const Maybe<ImageIntRegion>& aRegion,
+ uint32_t aFlags,
+ WebRenderImageProvider** aProvider) {
+ if (IsNonAnimated()) {
+ return InnerImage()->GetImageProvider(aRenderer, aSize, aSVGContext,
+ aRegion, aFlags, aProvider);
+ }
+
+ // XXX(seth): GetImageContainer does not currently support anything but the
+ // current frame. We work around this by always returning null, but if it ever
+ // turns out that FrozenImage is widely used on codepaths that can actually
+ // benefit from GetImageContainer, it would be a good idea to fix that method
+ // for performance reasons.
+ return ImgDrawResult::NOT_SUPPORTED;
+}
+
+NS_IMETHODIMP_(ImgDrawResult)
+FrozenImage::Draw(gfxContext* aContext, const nsIntSize& aSize,
+ const ImageRegion& aRegion,
+ uint32_t /* aWhichFrame - ignored */,
+ SamplingFilter aSamplingFilter,
+ const SVGImageContext& aSVGContext, uint32_t aFlags,
+ float aOpacity) {
+ return InnerImage()->Draw(aContext, aSize, aRegion, FRAME_FIRST,
+ aSamplingFilter, aSVGContext, aFlags, aOpacity);
+}
+
+NS_IMETHODIMP
+FrozenImage::StartDecoding(uint32_t aFlags, uint32_t aWhichFrame) {
+ return InnerImage()->StartDecoding(aFlags, FRAME_FIRST);
+}
+
+bool FrozenImage::StartDecodingWithResult(uint32_t aFlags,
+ uint32_t aWhichFrame) {
+ return InnerImage()->StartDecodingWithResult(aFlags, FRAME_FIRST);
+}
+
+bool FrozenImage::HasDecodedPixels() {
+ return InnerImage()->HasDecodedPixels();
+}
+
+imgIContainer::DecodeResult FrozenImage::RequestDecodeWithResult(
+ uint32_t aFlags, uint32_t aWhichFrame) {
+ return InnerImage()->RequestDecodeWithResult(aFlags, FRAME_FIRST);
+}
+
+NS_IMETHODIMP
+FrozenImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags,
+ uint32_t aWhichFrame) {
+ return InnerImage()->RequestDecodeForSize(aSize, aFlags, FRAME_FIRST);
+}
+
+NS_IMETHODIMP_(void)
+FrozenImage::RequestRefresh(const TimeStamp& aTime) {
+ // Do nothing.
+}
+
+NS_IMETHODIMP
+FrozenImage::GetAnimationMode(uint16_t* aAnimationMode) {
+ *aAnimationMode = kNormalAnimMode;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FrozenImage::SetAnimationMode(uint16_t aAnimationMode) {
+ // Do nothing.
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FrozenImage::ResetAnimation() {
+ // Do nothing.
+ return NS_OK;
+}
+
+NS_IMETHODIMP_(float)
+FrozenImage::GetFrameIndex(uint32_t aWhichFrame) {
+ MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE, "Invalid argument");
+ return 0;
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/FrozenImage.h b/image/FrozenImage.h
new file mode 100644
index 0000000000..6f580c826c
--- /dev/null
+++ b/image/FrozenImage.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_FrozenImage_h
+#define mozilla_image_FrozenImage_h
+
+#include "ImageWrapper.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
+
+namespace mozilla {
+namespace image {
+
+/**
+ * An Image wrapper that disables animation, freezing the image at its first
+ * frame. It does this using two strategies. If this is the only instance of the
+ * image, animation will never start, because IncrementAnimationConsumers is
+ * ignored. If there is another instance that is animated, that's still OK,
+ * because any imgIContainer method that is affected by animation gets its
+ * aWhichFrame argument set to FRAME_FIRST when it passes through FrozenImage.
+ *
+ * XXX(seth): There a known (performance, not correctness) issue with
+ * GetImageContainer. See the comments for that method for more information.
+ */
+class FrozenImage : public ImageWrapper {
+ typedef gfx::SourceSurface SourceSurface;
+
+ public:
+ NS_INLINE_DECL_REFCOUNTING_INHERITED(FrozenImage, ImageWrapper)
+
+ virtual void IncrementAnimationConsumers() override;
+ virtual void DecrementAnimationConsumers() override;
+
+ bool IsNonAnimated() const;
+
+ NS_IMETHOD GetAnimated(bool* aAnimated) override;
+ NS_IMETHOD_(already_AddRefed<SourceSurface>)
+ GetFrame(uint32_t aWhichFrame, uint32_t aFlags) override;
+ NS_IMETHOD_(already_AddRefed<SourceSurface>)
+ GetFrameAtSize(const gfx::IntSize& aSize, uint32_t aWhichFrame,
+ uint32_t aFlags) override;
+ NS_IMETHOD_(bool)
+ IsImageContainerAvailable(WindowRenderer* aRenderer,
+ uint32_t aFlags) override;
+ NS_IMETHOD_(ImgDrawResult)
+ GetImageProvider(WindowRenderer* aRenderer, const gfx::IntSize& aSize,
+ const SVGImageContext& aSVGContext,
+ const Maybe<ImageIntRegion>& aRegion, uint32_t aFlags,
+ WebRenderImageProvider** aProvider) override;
+ NS_IMETHOD_(ImgDrawResult)
+ Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion,
+ uint32_t aWhichFrame, gfx::SamplingFilter aSamplingFilter,
+ const SVGImageContext& aSVGContext, uint32_t aFlags,
+ float aOpacity) override;
+ NS_IMETHOD StartDecoding(uint32_t aFlags, uint32_t aWhichFrame) override;
+ NS_IMETHOD_(bool)
+ StartDecodingWithResult(uint32_t aFlags, uint32_t aWhichFrame) override;
+ NS_IMETHOD_(bool)
+ HasDecodedPixels() override;
+ NS_IMETHOD_(DecodeResult)
+ RequestDecodeWithResult(uint32_t aFlags, uint32_t aWhichFrame) override;
+ NS_IMETHOD RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags,
+ uint32_t aWhichFrame) override;
+ NS_IMETHOD_(void) RequestRefresh(const TimeStamp& aTime) override;
+ NS_IMETHOD GetAnimationMode(uint16_t* aAnimationMode) override;
+ NS_IMETHOD SetAnimationMode(uint16_t aAnimationMode) override;
+ NS_IMETHOD ResetAnimation() override;
+ NS_IMETHOD_(float) GetFrameIndex(uint32_t aWhichFrame) override;
+
+ protected:
+ explicit FrozenImage(Image* aImage) : ImageWrapper(aImage) {}
+ virtual ~FrozenImage() {}
+
+ private:
+ friend class ImageOps;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_FrozenImage_h
diff --git a/image/ICOFileHeaders.h b/image/ICOFileHeaders.h
new file mode 100644
index 0000000000..a47919b91a
--- /dev/null
+++ b/image/ICOFileHeaders.h
@@ -0,0 +1,77 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_ICOFileHeaders_h
+#define mozilla_image_ICOFileHeaders_h
+
+namespace mozilla {
+namespace image {
+
+#define ICONFILEHEADERSIZE 6
+#define ICODIRENTRYSIZE 16
+#define PNGSIGNATURESIZE 8
+#define BMPFILEHEADERSIZE 14
+
+/**
+ * The header that comes right at the start of an icon file. (This
+ * corresponds to the Windows ICONDIR structure.)
+ */
+struct IconFileHeader {
+ /**
+ * Must be set to 0;
+ */
+ uint16_t mReserved;
+ /**
+ * 1 for icon (.ICO) image (or 2 for cursor (.CUR) image (icon with the
+ * addition of a hotspot), but we don't support cursor).
+ */
+ uint16_t mType;
+ /**
+ * The number of BMP/PNG images contained in the icon file.
+ */
+ uint16_t mCount;
+};
+
+/**
+ * For each BMP/PNG image that the icon file contains there must be a
+ * corresponding icon dir entry. (This corresponds to the Windows
+ * ICONDIRENTRY structure.) These entries are encoded directly after the
+ * IconFileHeader.
+ */
+struct IconDirEntry {
+ uint8_t mWidth;
+ uint8_t mHeight;
+ /**
+ * The number of colors in the color palette of the BMP/PNG that this dir
+ * entry corresponds to, or 0 if the image does not use a color palette.
+ */
+ uint8_t mColorCount;
+ /**
+ * Should be set to 0.
+ */
+ uint8_t mReserved;
+ union {
+ uint16_t mPlanes; // ICO
+ uint16_t mXHotspot; // CUR
+ };
+ union {
+ uint16_t mBitCount; // ICO (bits per pixel)
+ uint16_t mYHotspot; // CUR
+ };
+ /**
+ * "bytes in resource" is the length of the encoded BMP/PNG that this dir
+ * entry corresponds to.
+ */
+ uint32_t mBytesInRes;
+ /**
+ * The offset of the start of the encoded BMP/PNG that this dir entry
+ * corresponds to (from the start of the icon file).
+ */
+ uint32_t mImageOffset;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_ICOFileHeaders_h
diff --git a/image/IDecodingTask.cpp b/image/IDecodingTask.cpp
new file mode 100644
index 0000000000..1816c9056b
--- /dev/null
+++ b/image/IDecodingTask.cpp
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "IDecodingTask.h"
+
+#include "nsThreadUtils.h"
+#include "mozilla/AppShutdown.h"
+
+#include "Decoder.h"
+#include "DecodePool.h"
+#include "RasterImage.h"
+#include "SurfaceCache.h"
+
+namespace mozilla {
+
+using gfx::IntRect;
+
+namespace image {
+
+///////////////////////////////////////////////////////////////////////////////
+// Helpers for sending notifications to the image associated with a decoder.
+///////////////////////////////////////////////////////////////////////////////
+
+void IDecodingTask::EnsureHasEventTarget(NotNull<RasterImage*> aImage) {
+ if (!mEventTarget) {
+ // We determine the event target as late as possible, at the first dispatch
+ // time, because the observers bound to an imgRequest will affect it.
+ // We cache it rather than query for the event target each time because the
+ // event target can change. We don't want to risk events being executed in
+ // a different order than they are dispatched, which can happen if we
+ // selected scheduler groups which have no ordering guarantees relative to
+ // each other (e.g. it moves from scheduler group A for doc group DA to
+ // scheduler group B for doc group DB due to changing observers -- if we
+ // dispatched the first event on A, and the second on B, we don't know which
+ // will execute first.)
+ RefPtr<ProgressTracker> tracker = aImage->GetProgressTracker();
+ if (tracker) {
+ mEventTarget = tracker->GetEventTarget();
+ } else {
+ mEventTarget = GetMainThreadSerialEventTarget();
+ }
+ }
+}
+
+bool IDecodingTask::IsOnEventTarget() const {
+ // This is essentially equivalent to NS_IsOnMainThread() because all of the
+ // event targets are for the main thread (although perhaps with a different
+ // label / scheduler group). The observers in ProgressTracker may have
+ // different event targets from this, so this is just a best effort guess.
+ bool current = false;
+ mEventTarget->IsOnCurrentThread(&current);
+ return current;
+}
+
+void IDecodingTask::NotifyProgress(NotNull<RasterImage*> aImage,
+ NotNull<Decoder*> aDecoder) {
+ MOZ_ASSERT(aDecoder->HasProgress() && !aDecoder->IsMetadataDecode());
+ EnsureHasEventTarget(aImage);
+
+ // Capture the decoder's state. If we need to notify asynchronously, it's
+ // important that we don't wait until the lambda actually runs to capture the
+ // state that we're going to notify. That would both introduce data races on
+ // the decoder's state and cause inconsistencies between the NotifyProgress()
+ // calls we make off-main-thread and the notifications that RasterImage
+ // actually receives, which would cause bugs.
+ Progress progress = aDecoder->TakeProgress();
+ OrientedIntRect invalidRect = aDecoder->TakeInvalidRect();
+ Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount();
+ DecoderFlags decoderFlags = aDecoder->GetDecoderFlags();
+ SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags();
+
+ // Synchronously notify if we can.
+ if (IsOnEventTarget() && !(decoderFlags & DecoderFlags::ASYNC_NOTIFY)) {
+ aImage->NotifyProgress(progress, invalidRect, frameCount, decoderFlags,
+ surfaceFlags);
+ return;
+ }
+
+ // Don't try to dispatch after shutdown, we'll just leak the runnable.
+ if (NS_WARN_IF(
+ AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownThreads))) {
+ return;
+ }
+
+ // We're forced to notify asynchronously.
+ NotNull<RefPtr<RasterImage>> image = aImage;
+ mEventTarget->Dispatch(CreateRenderBlockingRunnable(NS_NewRunnableFunction(
+ "IDecodingTask::NotifyProgress",
+ [=]() -> void {
+ image->NotifyProgress(progress, invalidRect,
+ frameCount, decoderFlags,
+ surfaceFlags);
+ })),
+ NS_DISPATCH_NORMAL);
+}
+
+void IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage,
+ NotNull<Decoder*> aDecoder) {
+ MOZ_ASSERT(aDecoder->HasError() || !aDecoder->InFrame(),
+ "Decode complete in the middle of a frame?");
+ EnsureHasEventTarget(aImage);
+
+ // Capture the decoder's state.
+ DecoderFinalStatus finalStatus = aDecoder->FinalStatus();
+ ImageMetadata metadata = aDecoder->GetImageMetadata();
+ DecoderTelemetry telemetry = aDecoder->Telemetry();
+ Progress progress = aDecoder->TakeProgress();
+ OrientedIntRect invalidRect = aDecoder->TakeInvalidRect();
+ Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount();
+ DecoderFlags decoderFlags = aDecoder->GetDecoderFlags();
+ SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags();
+
+ // Synchronously notify if we can.
+ if (IsOnEventTarget() && !(decoderFlags & DecoderFlags::ASYNC_NOTIFY)) {
+ aImage->NotifyDecodeComplete(finalStatus, metadata, telemetry, progress,
+ invalidRect, frameCount, decoderFlags,
+ surfaceFlags);
+ return;
+ }
+
+ // Don't try to dispatch after shutdown, we'll just leak the runnable.
+ if (NS_WARN_IF(
+ AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownThreads))) {
+ return;
+ }
+
+ // We're forced to notify asynchronously.
+ NotNull<RefPtr<RasterImage>> image = aImage;
+ mEventTarget->Dispatch(CreateRenderBlockingRunnable(NS_NewRunnableFunction(
+ "IDecodingTask::NotifyDecodeComplete",
+ [=]() -> void {
+ image->NotifyDecodeComplete(
+ finalStatus, metadata, telemetry, progress,
+ invalidRect, frameCount, decoderFlags,
+ surfaceFlags);
+ })),
+ NS_DISPATCH_NORMAL);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// IDecodingTask implementation.
+///////////////////////////////////////////////////////////////////////////////
+
+void IDecodingTask::Resume() { DecodePool::Singleton()->AsyncRun(this); }
+
+///////////////////////////////////////////////////////////////////////////////
+// MetadataDecodingTask implementation.
+///////////////////////////////////////////////////////////////////////////////
+
+MetadataDecodingTask::MetadataDecodingTask(NotNull<Decoder*> aDecoder)
+ : mMutex("mozilla::image::MetadataDecodingTask"), mDecoder(aDecoder) {
+ MOZ_ASSERT(mDecoder->IsMetadataDecode(),
+ "Use DecodingTask for non-metadata decodes");
+}
+
+void MetadataDecodingTask::Run() {
+ MutexAutoLock lock(mMutex);
+
+ LexerResult result = mDecoder->Decode(WrapNotNull(this));
+
+ if (result.is<TerminalState>()) {
+ NotifyDecodeComplete(mDecoder->GetImage(), mDecoder);
+ return; // We're done.
+ }
+
+ if (result == LexerResult(Yield::NEED_MORE_DATA)) {
+ // We can't make any more progress right now. We also don't want to report
+ // any progress, because it's important that metadata decode results are
+ // delivered atomically. The decoder itself will ensure that we get
+ // reenqueued when more data is available; just return for now.
+ return;
+ }
+
+ MOZ_ASSERT_UNREACHABLE("Metadata decode yielded for an unexpected reason");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// AnonymousDecodingTask implementation.
+///////////////////////////////////////////////////////////////////////////////
+
+AnonymousDecodingTask::AnonymousDecodingTask(NotNull<Decoder*> aDecoder,
+ bool aResumable)
+ : mDecoder(aDecoder), mResumable(aResumable) {}
+
+void AnonymousDecodingTask::Run() {
+ while (true) {
+ LexerResult result = mDecoder->Decode(WrapNotNull(this));
+
+ if (result.is<TerminalState>()) {
+ return; // We're done.
+ }
+
+ if (result == LexerResult(Yield::NEED_MORE_DATA)) {
+ // We can't make any more progress right now. Let the caller decide how to
+ // handle it.
+ return;
+ }
+
+ // Right now we don't do anything special for other kinds of yields, so just
+ // keep working.
+ MOZ_ASSERT(result.is<Yield>());
+ }
+}
+
+void AnonymousDecodingTask::Resume() {
+ // Anonymous decoders normally get all their data at once. We have tests
+ // where they don't; typically in these situations, the test re-runs them
+ // manually. However some tests want to verify Resume works, so they will
+ // explicitly request this behaviour.
+ if (mResumable) {
+ RefPtr<AnonymousDecodingTask> self(this);
+ NS_DispatchToMainThread(
+ NS_NewRunnableFunction("image::AnonymousDecodingTask::Resume",
+ [self]() -> void { self->Run(); }));
+ }
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/IDecodingTask.h b/image/IDecodingTask.h
new file mode 100644
index 0000000000..b3bce74757
--- /dev/null
+++ b/image/IDecodingTask.h
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * An interface for tasks which can execute on the ImageLib DecodePool, and
+ * various implementations.
+ */
+
+#ifndef mozilla_image_IDecodingTask_h
+#define mozilla_image_IDecodingTask_h
+
+#include "imgFrame.h"
+#include "mozilla/NotNull.h"
+#include "mozilla/RefPtr.h"
+#include "nsIEventTarget.h"
+#include "SourceBuffer.h"
+
+namespace mozilla {
+namespace image {
+
+class Decoder;
+class RasterImage;
+
+/// A priority hint that DecodePool can use when scheduling an IDecodingTask.
+enum class TaskPriority : uint8_t { eLow, eHigh };
+
+/**
+ * An interface for tasks which can execute on the ImageLib DecodePool.
+ */
+class IDecodingTask : public IResumable {
+ public:
+ /// Run the task.
+ virtual void Run() = 0;
+
+ /// @return true if, given the option, this task prefers to run synchronously.
+ virtual bool ShouldPreferSyncRun() const = 0;
+
+ /// @return a priority hint that DecodePool can use when scheduling this task.
+ virtual TaskPriority Priority() const = 0;
+
+ /// A default implementation of IResumable which resubmits the task to the
+ /// DecodePool. Subclasses can override this if they need different behavior.
+ void Resume() override;
+
+ protected:
+ virtual ~IDecodingTask() {}
+
+ /// Notify @aImage of @aDecoder's progress.
+ void NotifyProgress(NotNull<RasterImage*> aImage, NotNull<Decoder*> aDecoder);
+
+ /// Notify @aImage that @aDecoder has finished.
+ void NotifyDecodeComplete(NotNull<RasterImage*> aImage,
+ NotNull<Decoder*> aDecoder);
+
+ private:
+ void EnsureHasEventTarget(NotNull<RasterImage*> aImage);
+
+ bool IsOnEventTarget() const;
+
+ nsCOMPtr<nsIEventTarget> mEventTarget;
+};
+
+/**
+ * An IDecodingTask implementation for metadata decodes of images.
+ */
+class MetadataDecodingTask final : public IDecodingTask {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MetadataDecodingTask, override)
+
+ explicit MetadataDecodingTask(NotNull<Decoder*> aDecoder);
+
+ void Run() override;
+
+ // Metadata decodes are very fast (since they only need to examine an image's
+ // header) so there's no reason to refuse to run them synchronously if the
+ // caller will allow us to.
+ bool ShouldPreferSyncRun() const override { return true; }
+
+ // Metadata decodes run at the highest priority because they block layout and
+ // page load.
+ TaskPriority Priority() const override { return TaskPriority::eHigh; }
+
+ private:
+ virtual ~MetadataDecodingTask() {}
+
+ /// Mutex protecting access to mDecoder.
+ Mutex mMutex MOZ_UNANNOTATED;
+
+ NotNull<RefPtr<Decoder>> mDecoder;
+};
+
+/**
+ * An IDecodingTask implementation for anonymous decoders - that is, decoders
+ * with no associated Image object.
+ */
+class AnonymousDecodingTask final : public IDecodingTask {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AnonymousDecodingTask, override)
+
+ explicit AnonymousDecodingTask(NotNull<Decoder*> aDecoder, bool aResumable);
+
+ void Run() override;
+
+ bool ShouldPreferSyncRun() const override { return true; }
+ TaskPriority Priority() const override { return TaskPriority::eLow; }
+
+ void Resume() override;
+
+ private:
+ virtual ~AnonymousDecodingTask() {}
+
+ NotNull<RefPtr<Decoder>> mDecoder;
+ bool mResumable;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_IDecodingTask_h
diff --git a/image/IProgressObserver.h b/image/IProgressObserver.h
new file mode 100644
index 0000000000..c4b16f70de
--- /dev/null
+++ b/image/IProgressObserver.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_IProgressObserver_h
+#define mozilla_image_IProgressObserver_h
+
+#include "mozilla/WeakPtr.h"
+#include "nsISupports.h"
+#include "nsRect.h"
+
+class nsIEventTarget;
+
+namespace mozilla {
+namespace image {
+
+/**
+ * An interface for observing changes to image state, as reported by
+ * ProgressTracker.
+ *
+ * This is the ImageLib-internal version of imgINotificationObserver,
+ * essentially, with implementation details that code outside of ImageLib
+ * shouldn't see.
+ *
+ * XXX(seth): It's preferable to avoid adding anything to this interface if
+ * possible. In the long term, it would be ideal to get to a place where we can
+ * just use the imgINotificationObserver interface internally as well.
+ */
+class IProgressObserver : public SupportsWeakPtr {
+ public:
+ // Subclasses may or may not be XPCOM classes, so we just require that they
+ // implement AddRef and Release.
+ NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
+
+ // imgINotificationObserver methods:
+ virtual void Notify(int32_t aType, const nsIntRect* aRect = nullptr) = 0;
+ virtual void OnLoadComplete(bool aLastPart) = 0;
+
+ // Other, internal-only methods:
+ virtual void SetHasImage() = 0;
+ virtual bool NotificationsDeferred() const = 0;
+ virtual void MarkPendingNotify() = 0;
+ virtual void ClearPendingNotify() = 0;
+
+ virtual already_AddRefed<nsIEventTarget> GetEventTarget() const {
+ return nullptr;
+ }
+
+ protected:
+ virtual ~IProgressObserver() = default;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_IProgressObserver_h
diff --git a/image/ISurfaceProvider.h b/image/ISurfaceProvider.h
new file mode 100644
index 0000000000..03ab713238
--- /dev/null
+++ b/image/ISurfaceProvider.h
@@ -0,0 +1,346 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * An interface for objects which can either store a surface or dynamically
+ * generate one, and various implementations.
+ */
+
+#ifndef mozilla_image_ISurfaceProvider_h
+#define mozilla_image_ISurfaceProvider_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/NotNull.h"
+#include "mozilla/TimeStamp.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/image/WebRenderImageProvider.h"
+
+#include "imgFrame.h"
+#include "SurfaceCache.h"
+
+namespace mozilla {
+namespace image {
+
+class CachedSurface;
+class DrawableSurface;
+
+/**
+ * An interface for objects which can either store a surface or dynamically
+ * generate one.
+ */
+class ISurfaceProvider : public WebRenderImageProvider {
+ public:
+ // Subclasses may or may not be XPCOM classes, so we just require that they
+ // implement AddRef and Release.
+ NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
+
+ /// @return key data used for identifying which image this ISurfaceProvider is
+ /// associated with in the surface cache.
+ ImageKey GetImageKey() const { return mImageKey; }
+
+ /// @return key data used to uniquely identify this ISurfaceProvider's cache
+ /// entry in the surface cache.
+ const SurfaceKey& GetSurfaceKey() const { return mSurfaceKey; }
+
+ /// @return a drawable reference to a surface.
+ DrawableSurface Surface();
+
+ /// @return true if DrawableRef() will return a completely decoded surface.
+ virtual bool IsFinished() const = 0;
+
+ /// @return true if the underlying decoder is currently fully decoded. For
+ /// animated images, this means that at least every frame has been decoded
+ /// at least once. It does not guarantee that all of the frames are present,
+ /// as the surface provider has the option to discard as it deems necessary.
+ virtual bool IsFullyDecoded() const { return IsFinished(); }
+
+ /// @return the number of bytes of memory this ISurfaceProvider is expected to
+ /// require. Optimizations may result in lower real memory usage. Trivial
+ /// overhead is ignored. Because this value is used in bookkeeping, it's
+ /// important that it be constant over the lifetime of this object.
+ virtual size_t LogicalSizeInBytes() const = 0;
+
+ typedef imgFrame::AddSizeOfCbData AddSizeOfCbData;
+ typedef imgFrame::AddSizeOfCb AddSizeOfCb;
+
+ /// @return the actual number of bytes of memory this ISurfaceProvider is
+ /// using. May vary over the lifetime of the ISurfaceProvider. The default
+ /// implementation is appropriate for static ISurfaceProviders.
+ virtual void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
+ const AddSizeOfCb& aCallback) {
+ DrawableFrameRef ref = DrawableRef(/* aFrame = */ 0);
+ if (!ref) {
+ return;
+ }
+
+ ref->AddSizeOfExcludingThis(aMallocSizeOf, aCallback);
+ }
+
+ virtual void Reset() {}
+ virtual void Advance(size_t aFrame) {}
+ virtual bool MayAdvance() const { return false; }
+ virtual void MarkMayAdvance() {}
+
+ /// @return the availability state of this ISurfaceProvider, which indicates
+ /// whether DrawableRef() could successfully return a surface. Should only be
+ /// called from SurfaceCache code as it relies on SurfaceCache for
+ /// synchronization.
+ AvailabilityState& Availability() { return mAvailability; }
+ const AvailabilityState& Availability() const { return mAvailability; }
+
+ protected:
+ ISurfaceProvider(const ImageKey aImageKey, const SurfaceKey& aSurfaceKey,
+ AvailabilityState aAvailability)
+ : WebRenderImageProvider(aImageKey),
+ mImageKey(aImageKey),
+ mSurfaceKey(aSurfaceKey),
+ mAvailability(aAvailability) {
+ MOZ_ASSERT(aImageKey, "Must have a valid image key");
+ }
+
+ virtual ~ISurfaceProvider() {}
+
+ /// @return an eagerly computed drawable reference to a surface. For
+ /// dynamically generated animation surfaces, @aFrame specifies the 0-based
+ /// index of the desired frame.
+ virtual DrawableFrameRef DrawableRef(size_t aFrame) = 0;
+
+ /// @return an imgFrame at the 0-based index of the desired frame, as
+ /// specified by @aFrame. Only applies for animated images.
+ virtual already_AddRefed<imgFrame> GetFrame(size_t aFrame) {
+ MOZ_ASSERT_UNREACHABLE("Surface provider does not support direct access!");
+ return nullptr;
+ }
+
+ /// @return true if this ISurfaceProvider is locked. (@see SetLocked())
+ /// Should only be called from SurfaceCache code as it relies on SurfaceCache
+ /// for synchronization.
+ virtual bool IsLocked() const = 0;
+
+ /// If @aLocked is true, hint that this ISurfaceProvider is in use and it
+ /// should avoid releasing its resources. Should only be called from
+ /// SurfaceCache code as it relies on SurfaceCache for synchronization.
+ virtual void SetLocked(bool aLocked) = 0;
+
+ private:
+ friend class CachedSurface;
+ friend class DrawableSurface;
+
+ const ImageKey mImageKey;
+ const SurfaceKey mSurfaceKey;
+ AvailabilityState mAvailability;
+};
+
+/**
+ * A reference to a surface (stored in an imgFrame) that holds the surface in
+ * memory, guaranteeing that it can be drawn. If you have a DrawableSurface
+ * |surf| and |if (surf)| returns true, then calls to |surf->Draw()| and
+ * |surf->GetSourceSurface()| are guaranteed to succeed.
+ *
+ * Note that the surface may be computed lazily, so a DrawableSurface should not
+ * be dereferenced (i.e., operator->() should not be called) until you're
+ * sure that you want to draw it.
+ */
+class MOZ_STACK_CLASS DrawableSurface final {
+ public:
+ DrawableSurface() : mHaveSurface(false) {}
+
+ explicit DrawableSurface(NotNull<ISurfaceProvider*> aProvider)
+ : mProvider(aProvider), mHaveSurface(true) {}
+
+ DrawableSurface(DrawableSurface&& aOther)
+ : mDrawableRef(std::move(aOther.mDrawableRef)),
+ mProvider(std::move(aOther.mProvider)),
+ mHaveSurface(aOther.mHaveSurface) {
+ aOther.mHaveSurface = false;
+ }
+
+ DrawableSurface& operator=(DrawableSurface&& aOther) {
+ MOZ_ASSERT(this != &aOther, "Self-moves are prohibited");
+ mDrawableRef = std::move(aOther.mDrawableRef);
+ mProvider = std::move(aOther.mProvider);
+ mHaveSurface = aOther.mHaveSurface;
+ aOther.mHaveSurface = false;
+ return *this;
+ }
+
+ /**
+ * If this DrawableSurface is dynamically generated from an animation, attempt
+ * to seek to frame @aFrame, where @aFrame is a 0-based index into the frames
+ * of the animation. Otherwise, nothing will blow up at runtime, but we assert
+ * in debug builds, since calling this in an unexpected situation probably
+ * indicates a bug.
+ *
+ * @return a successful result if we could obtain frame @aFrame. Note that
+ * |mHaveSurface| being true means that we're guaranteed to have *some* frame,
+ * so the caller can dereference this DrawableSurface even if Seek() fails,
+ * but while nothing will blow up, the frame won't be the one they expect.
+ */
+ nsresult Seek(size_t aFrame) {
+ MOZ_ASSERT(mHaveSurface, "Trying to seek an empty DrawableSurface?");
+
+ if (!mProvider) {
+ MOZ_ASSERT_UNREACHABLE("Trying to seek a static DrawableSurface?");
+ return NS_ERROR_FAILURE;
+ }
+
+ mDrawableRef = mProvider->DrawableRef(aFrame);
+
+ return mDrawableRef ? NS_OK : NS_ERROR_FAILURE;
+ }
+
+ already_AddRefed<imgFrame> GetFrame(size_t aFrame) {
+ MOZ_ASSERT(mHaveSurface, "Trying to get on an empty DrawableSurface?");
+
+ if (!mProvider) {
+ MOZ_ASSERT_UNREACHABLE("Trying to get on a static DrawableSurface?");
+ return nullptr;
+ }
+
+ return mProvider->GetFrame(aFrame);
+ }
+
+ void Reset() {
+ if (!mProvider) {
+ MOZ_ASSERT_UNREACHABLE("Trying to reset a static DrawableSurface?");
+ return;
+ }
+
+ mProvider->Reset();
+ }
+
+ void Advance(size_t aFrame) {
+ if (!mProvider) {
+ MOZ_ASSERT_UNREACHABLE("Trying to advance a static DrawableSurface?");
+ return;
+ }
+
+ mProvider->Advance(aFrame);
+ }
+
+ bool MayAdvance() const {
+ if (!mProvider) {
+ MOZ_ASSERT_UNREACHABLE("Trying to advance a static DrawableSurface?");
+ return false;
+ }
+
+ return mProvider->MayAdvance();
+ }
+
+ void MarkMayAdvance() {
+ if (!mProvider) {
+ MOZ_ASSERT_UNREACHABLE("Trying to advance a static DrawableSurface?");
+ return;
+ }
+
+ mProvider->MarkMayAdvance();
+ }
+
+ bool IsFullyDecoded() const {
+ if (!mProvider) {
+ MOZ_ASSERT_UNREACHABLE(
+ "Trying to check decoding state of a static DrawableSurface?");
+ return false;
+ }
+
+ return mProvider->IsFullyDecoded();
+ }
+
+ void TakeProvider(WebRenderImageProvider** aOutProvider) {
+ mProvider.forget(aOutProvider);
+ }
+
+ explicit operator bool() const { return mHaveSurface; }
+ imgFrame* operator->() { return DrawableRef().get(); }
+
+ private:
+ DrawableSurface(const DrawableSurface& aOther) = delete;
+ DrawableSurface& operator=(const DrawableSurface& aOther) = delete;
+
+ DrawableFrameRef& DrawableRef() {
+ MOZ_ASSERT(mHaveSurface);
+
+ // If we weren't created with a DrawableFrameRef directly, we should've been
+ // created with an ISurfaceProvider which can give us one. Note that if
+ // Seek() has been called, we'll already have a DrawableFrameRef, so we
+ // won't need to get one here.
+ if (!mDrawableRef) {
+ MOZ_ASSERT(mProvider);
+ mDrawableRef = mProvider->DrawableRef(/* aFrame = */ 0);
+ }
+
+ MOZ_ASSERT(mDrawableRef);
+ return mDrawableRef;
+ }
+
+ DrawableFrameRef mDrawableRef;
+ RefPtr<ISurfaceProvider> mProvider;
+ bool mHaveSurface;
+};
+
+// Surface() is implemented here so that DrawableSurface's definition is
+// visible.
+inline DrawableSurface ISurfaceProvider::Surface() {
+ return DrawableSurface(WrapNotNull(this));
+}
+
+/**
+ * An ISurfaceProvider that stores a single surface.
+ */
+class SimpleSurfaceProvider final : public ISurfaceProvider {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SimpleSurfaceProvider, override)
+
+ SimpleSurfaceProvider(const ImageKey aImageKey, const SurfaceKey& aSurfaceKey,
+ NotNull<imgFrame*> aSurface)
+ : ISurfaceProvider(aImageKey, aSurfaceKey,
+ AvailabilityState::StartAvailable()),
+ mSurface(aSurface) {
+ MOZ_ASSERT(aSurfaceKey.Size() == mSurface->GetSize());
+ }
+
+ bool IsFinished() const override { return mSurface->IsFinished(); }
+
+ size_t LogicalSizeInBytes() const override {
+ gfx::IntSize size = mSurface->GetSize();
+ return size.width * size.height * mSurface->GetBytesPerPixel();
+ }
+
+ nsresult UpdateKey(layers::RenderRootStateManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources,
+ wr::ImageKey& aKey) override;
+
+ protected:
+ DrawableFrameRef DrawableRef(size_t aFrame) override {
+ MOZ_ASSERT(aFrame == 0,
+ "Requesting an animation frame from a SimpleSurfaceProvider?");
+ return mSurface->DrawableRef();
+ }
+
+ bool IsLocked() const override { return bool(mLockRef); }
+
+ void SetLocked(bool aLocked) override {
+ if (aLocked == IsLocked()) {
+ return; // Nothing changed.
+ }
+
+ // If we're locked, hold a DrawableFrameRef to |mSurface|, which will keep
+ // any volatile buffer it owns in memory.
+ mLockRef = aLocked ? mSurface->DrawableRef() : DrawableFrameRef();
+ }
+
+ private:
+ virtual ~SimpleSurfaceProvider() {}
+
+ NotNull<RefPtr<imgFrame>> mSurface;
+ DrawableFrameRef mLockRef;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_ISurfaceProvider_h
diff --git a/image/Image.cpp b/image/Image.cpp
new file mode 100644
index 0000000000..16f754f490
--- /dev/null
+++ b/image/Image.cpp
@@ -0,0 +1,261 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "Image.h"
+
+#include "imgRequest.h"
+#include "WebRenderImageProvider.h"
+#include "nsIObserverService.h"
+#include "nsRefreshDriver.h"
+#include "nsContentUtils.h"
+#include "mozilla/Atomics.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/gfx/Rect.h"
+#include "mozilla/gfx/SourceSurfaceRawData.h"
+#include "mozilla/Services.h"
+#include "mozilla/SizeOfState.h"
+#include "mozilla/TimeStamp.h"
+// for Tie
+#include "mozilla/layers/SharedSurfacesChild.h"
+
+namespace mozilla {
+namespace image {
+
+WebRenderImageProvider::WebRenderImageProvider(const ImageResource* aImage)
+ : mProviderId(aImage->GetImageProviderId()) {}
+
+/* static */ ImageProviderId WebRenderImageProvider::AllocateProviderId() {
+ // Callable on all threads.
+ static Atomic<ImageProviderId> sProviderId(0u);
+ return ++sProviderId;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Memory Reporting
+///////////////////////////////////////////////////////////////////////////////
+
+ImageMemoryCounter::ImageMemoryCounter(imgRequest* aRequest,
+ SizeOfState& aState, bool aIsUsed)
+ : mProgress(UINT32_MAX),
+ mType(UINT16_MAX),
+ mIsUsed(aIsUsed),
+ mHasError(false),
+ mValidating(false) {
+ MOZ_ASSERT(aRequest);
+
+ // We don't have the image object yet, but we can get some information.
+ nsCOMPtr<nsIURI> imageURL;
+ nsresult rv = aRequest->GetURI(getter_AddRefs(imageURL));
+ if (NS_SUCCEEDED(rv) && imageURL) {
+ imageURL->GetSpec(mURI);
+ }
+
+ mType = imgIContainer::TYPE_REQUEST;
+ mHasError = NS_FAILED(aRequest->GetImageErrorCode());
+ mValidating = !!aRequest->GetValidator();
+
+ RefPtr<ProgressTracker> tracker = aRequest->GetProgressTracker();
+ if (tracker) {
+ mProgress = tracker->GetProgress();
+ }
+}
+
+ImageMemoryCounter::ImageMemoryCounter(imgRequest* aRequest, Image* aImage,
+ SizeOfState& aState, bool aIsUsed)
+ : mProgress(UINT32_MAX),
+ mType(UINT16_MAX),
+ mIsUsed(aIsUsed),
+ mHasError(false),
+ mValidating(false) {
+ MOZ_ASSERT(aRequest);
+ MOZ_ASSERT(aImage);
+
+ // Extract metadata about the image.
+ nsCOMPtr<nsIURI> imageURL(aImage->GetURI());
+ if (imageURL) {
+ imageURL->GetSpec(mURI);
+ }
+
+ int32_t width = 0;
+ int32_t height = 0;
+ aImage->GetWidth(&width);
+ aImage->GetHeight(&height);
+ mIntrinsicSize.SizeTo(width, height);
+
+ mType = aImage->GetType();
+ mHasError = aImage->HasError();
+ mValidating = !!aRequest->GetValidator();
+
+ RefPtr<ProgressTracker> tracker = aImage->GetProgressTracker();
+ if (tracker) {
+ mProgress = tracker->GetProgress();
+ }
+
+ // Populate memory counters for source and decoded data.
+ mValues.SetSource(aImage->SizeOfSourceWithComputedFallback(aState));
+ aImage->CollectSizeOfSurfaces(mSurfaces, aState.mMallocSizeOf);
+
+ // Compute totals.
+ for (const SurfaceMemoryCounter& surfaceCounter : mSurfaces) {
+ mValues += surfaceCounter.Values();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Image Base Types
+///////////////////////////////////////////////////////////////////////////////
+
+bool ImageResource::GetSpecTruncatedTo1k(nsCString& aSpec) const {
+ static const size_t sMaxTruncatedLength = 1024;
+
+ mURI->GetSpec(aSpec);
+ if (sMaxTruncatedLength >= aSpec.Length()) {
+ return true;
+ }
+
+ aSpec.Truncate(sMaxTruncatedLength);
+ return false;
+}
+
+void ImageResource::CollectSizeOfSurfaces(
+ nsTArray<SurfaceMemoryCounter>& aCounters,
+ MallocSizeOf aMallocSizeOf) const {
+ SurfaceCache::CollectSizeOfSurfaces(ImageKey(this), aCounters, aMallocSizeOf);
+}
+
+// Constructor
+ImageResource::ImageResource(nsIURI* aURI)
+ : mURI(aURI),
+ mInnerWindowId(0),
+ mAnimationConsumers(0),
+ mAnimationMode(kNormalAnimMode),
+ mInitialized(false),
+ mAnimating(false),
+ mError(false),
+ mProviderId(WebRenderImageProvider::AllocateProviderId()) {}
+
+ImageResource::~ImageResource() {
+ // Ask our ProgressTracker to drop its weak reference to us.
+ mProgressTracker->ResetImage();
+}
+
+void ImageResource::IncrementAnimationConsumers() {
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Main thread only to encourage serialization "
+ "with DecrementAnimationConsumers");
+ mAnimationConsumers++;
+}
+
+void ImageResource::DecrementAnimationConsumers() {
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Main thread only to encourage serialization "
+ "with IncrementAnimationConsumers");
+ MOZ_ASSERT(mAnimationConsumers >= 1, "Invalid no. of animation consumers!");
+ mAnimationConsumers--;
+}
+
+nsresult ImageResource::GetAnimationModeInternal(uint16_t* aAnimationMode) {
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ NS_ENSURE_ARG_POINTER(aAnimationMode);
+
+ *aAnimationMode = mAnimationMode;
+ return NS_OK;
+}
+
+nsresult ImageResource::SetAnimationModeInternal(uint16_t aAnimationMode) {
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ NS_ASSERTION(aAnimationMode == kNormalAnimMode ||
+ aAnimationMode == kDontAnimMode ||
+ aAnimationMode == kLoopOnceAnimMode,
+ "Wrong Animation Mode is being set!");
+
+ mAnimationMode = aAnimationMode;
+
+ return NS_OK;
+}
+
+bool ImageResource::HadRecentRefresh(const TimeStamp& aTime) {
+ // Our threshold for "recent" is 1/2 of the default refresh-driver interval.
+ // This ensures that we allow for frame rates at least as fast as the
+ // refresh driver's default rate.
+ static TimeDuration recentThreshold =
+ TimeDuration::FromMilliseconds(nsRefreshDriver::DefaultInterval() / 2.0);
+
+ if (!mLastRefreshTime.IsNull() &&
+ aTime - mLastRefreshTime < recentThreshold) {
+ return true;
+ }
+
+ // else, we can proceed with a refresh.
+ // But first, update our last refresh time:
+ mLastRefreshTime = aTime;
+ return false;
+}
+
+void ImageResource::EvaluateAnimation() {
+ if (!mAnimating && ShouldAnimate()) {
+ nsresult rv = StartAnimation();
+ mAnimating = NS_SUCCEEDED(rv);
+ } else if (mAnimating && !ShouldAnimate()) {
+ StopAnimation();
+ }
+}
+
+void ImageResource::SendOnUnlockedDraw(uint32_t aFlags) {
+ if (!mProgressTracker) {
+ return;
+ }
+
+ if (!(aFlags & FLAG_ASYNC_NOTIFY)) {
+ mProgressTracker->OnUnlockedDraw();
+ } else {
+ NotNull<RefPtr<ImageResource>> image = WrapNotNull(this);
+ nsCOMPtr<nsIEventTarget> eventTarget = mProgressTracker->GetEventTarget();
+ nsCOMPtr<nsIRunnable> ev = NS_NewRunnableFunction(
+ "image::ImageResource::SendOnUnlockedDraw", [=]() -> void {
+ RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
+ if (tracker) {
+ tracker->OnUnlockedDraw();
+ }
+ });
+ eventTarget->Dispatch(CreateRenderBlockingRunnable(ev.forget()),
+ NS_DISPATCH_NORMAL);
+ }
+}
+
+#ifdef DEBUG
+void ImageResource::NotifyDrawingObservers() {
+ if (!mURI || !NS_IsMainThread()) {
+ return;
+ }
+
+ if (!mURI->SchemeIs("resource") && !mURI->SchemeIs("chrome")) {
+ return;
+ }
+
+ // Record the image drawing for startup performance testing.
+ nsCOMPtr<nsIURI> uri = mURI;
+ nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
+ "image::ImageResource::NotifyDrawingObservers", [uri]() {
+ nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+ NS_WARNING_ASSERTION(obs, "Can't get an observer service handle");
+ if (obs) {
+ nsAutoCString spec;
+ uri->GetSpec(spec);
+ obs->NotifyObservers(nullptr, "image-drawing",
+ NS_ConvertUTF8toUTF16(spec).get());
+ }
+ }));
+}
+#endif
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/Image.h b/image/Image.h
new file mode 100644
index 0000000000..cd4ca926d0
--- /dev/null
+++ b/image/Image.h
@@ -0,0 +1,419 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_Image_h
+#define mozilla_image_Image_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/ProfilerMarkers.h"
+#include "mozilla/SizeOfState.h"
+#include "mozilla/ThreadSafeWeakPtr.h"
+#include "mozilla/TimeStamp.h"
+
+#include "gfx2DGlue.h"
+#include "imgIContainer.h"
+#include "ImageContainer.h"
+#include "ImageRegion.h"
+#include "LookupResult.h"
+#include "nsStringFwd.h"
+#include "ProgressTracker.h"
+#include "SurfaceCache.h"
+#include "WebRenderImageProvider.h"
+
+class imgRequest;
+class nsIRequest;
+class nsIInputStream;
+
+namespace mozilla {
+namespace image {
+
+class Image;
+
+///////////////////////////////////////////////////////////////////////////////
+// Memory Reporting
+///////////////////////////////////////////////////////////////////////////////
+
+struct MemoryCounter {
+ MemoryCounter()
+ : mSource(0),
+ mDecodedHeap(0),
+ mDecodedNonHeap(0),
+ mDecodedUnknown(0),
+ mExternalHandles(0),
+ mFrameIndex(0),
+ mExternalId(0),
+ mSurfaceTypes(0) {}
+
+ void SetSource(size_t aCount) { mSource = aCount; }
+ size_t Source() const { return mSource; }
+ void SetDecodedHeap(size_t aCount) { mDecodedHeap = aCount; }
+ size_t DecodedHeap() const { return mDecodedHeap; }
+ void SetDecodedNonHeap(size_t aCount) { mDecodedNonHeap = aCount; }
+ size_t DecodedNonHeap() const { return mDecodedNonHeap; }
+ void SetDecodedUnknown(size_t aCount) { mDecodedUnknown = aCount; }
+ size_t DecodedUnknown() const { return mDecodedUnknown; }
+ void SetExternalHandles(size_t aCount) { mExternalHandles = aCount; }
+ size_t ExternalHandles() const { return mExternalHandles; }
+ void SetFrameIndex(size_t aIndex) { mFrameIndex = aIndex; }
+ size_t FrameIndex() const { return mFrameIndex; }
+ void SetExternalId(uint64_t aId) { mExternalId = aId; }
+ uint64_t ExternalId() const { return mExternalId; }
+ void SetSurfaceTypes(uint32_t aTypes) { mSurfaceTypes = aTypes; }
+ uint32_t SurfaceTypes() const { return mSurfaceTypes; }
+
+ MemoryCounter& operator+=(const MemoryCounter& aOther) {
+ mSource += aOther.mSource;
+ mDecodedHeap += aOther.mDecodedHeap;
+ mDecodedNonHeap += aOther.mDecodedNonHeap;
+ mDecodedUnknown += aOther.mDecodedUnknown;
+ mExternalHandles += aOther.mExternalHandles;
+ mSurfaceTypes |= aOther.mSurfaceTypes;
+ return *this;
+ }
+
+ private:
+ size_t mSource;
+ size_t mDecodedHeap;
+ size_t mDecodedNonHeap;
+ size_t mDecodedUnknown;
+ size_t mExternalHandles;
+ size_t mFrameIndex;
+ uint64_t mExternalId;
+ uint32_t mSurfaceTypes;
+};
+
+enum class SurfaceMemoryCounterType { NORMAL, CONTAINER };
+
+struct SurfaceMemoryCounter {
+ SurfaceMemoryCounter(
+ const SurfaceKey& aKey, bool aIsLocked, bool aCannotSubstitute,
+ bool aIsFactor2, bool aFinished,
+ SurfaceMemoryCounterType aType = SurfaceMemoryCounterType::NORMAL)
+ : mKey(aKey),
+ mType(aType),
+ mIsLocked(aIsLocked),
+ mCannotSubstitute(aCannotSubstitute),
+ mIsFactor2(aIsFactor2),
+ mFinished(aFinished) {}
+
+ const SurfaceKey& Key() const { return mKey; }
+ MemoryCounter& Values() { return mValues; }
+ const MemoryCounter& Values() const { return mValues; }
+ SurfaceMemoryCounterType Type() const { return mType; }
+ bool IsLocked() const { return mIsLocked; }
+ bool CannotSubstitute() const { return mCannotSubstitute; }
+ bool IsFactor2() const { return mIsFactor2; }
+ bool IsFinished() const { return mFinished; }
+
+ private:
+ const SurfaceKey mKey;
+ MemoryCounter mValues;
+ const SurfaceMemoryCounterType mType;
+ const bool mIsLocked;
+ const bool mCannotSubstitute;
+ const bool mIsFactor2;
+ const bool mFinished;
+};
+
+struct ImageMemoryCounter {
+ ImageMemoryCounter(imgRequest* aRequest, SizeOfState& aState, bool aIsUsed);
+ ImageMemoryCounter(imgRequest* aRequest, Image* aImage, SizeOfState& aState,
+ bool aIsUsed);
+
+ nsCString& URI() { return mURI; }
+ const nsCString& URI() const { return mURI; }
+ const nsTArray<SurfaceMemoryCounter>& Surfaces() const { return mSurfaces; }
+ const gfx::IntSize IntrinsicSize() const { return mIntrinsicSize; }
+ const MemoryCounter& Values() const { return mValues; }
+ uint32_t Progress() const { return mProgress; }
+ uint16_t Type() const { return mType; }
+ bool IsUsed() const { return mIsUsed; }
+ bool HasError() const { return mHasError; }
+ bool IsValidating() const { return mValidating; }
+
+ bool IsNotable() const {
+ // Errors or requests without images are always notable.
+ if (mHasError || mValidating || mProgress == UINT32_MAX ||
+ mProgress & FLAG_HAS_ERROR || mType == imgIContainer::TYPE_REQUEST) {
+ return true;
+ }
+
+ // Sufficiently large images are notable.
+ const size_t NotableThreshold = 16 * 1024;
+ size_t total = mValues.Source() + mValues.DecodedHeap() +
+ mValues.DecodedNonHeap() + mValues.DecodedUnknown();
+ if (total >= NotableThreshold) {
+ return true;
+ }
+
+ // Incomplete images are always notable as well; the odds of capturing
+ // mid-decode should be fairly low.
+ for (const auto& surface : mSurfaces) {
+ if (!surface.IsFinished()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private:
+ nsCString mURI;
+ nsTArray<SurfaceMemoryCounter> mSurfaces;
+ gfx::IntSize mIntrinsicSize;
+ MemoryCounter mValues;
+ uint32_t mProgress;
+ uint16_t mType;
+ const bool mIsUsed;
+ bool mHasError;
+ bool mValidating;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Image Base Types
+///////////////////////////////////////////////////////////////////////////////
+
+class Image : public imgIContainer {
+ public:
+ /**
+ * Flags for Image initialization.
+ *
+ * Meanings:
+ *
+ * INIT_FLAG_NONE: Lack of flags
+ *
+ * INIT_FLAG_DISCARDABLE: The container should be discardable
+ *
+ * INIT_FLAG_DECODE_IMMEDIATELY: The container should decode as soon as
+ * possible, regardless of what our heuristics say.
+ *
+ * INIT_FLAG_TRANSIENT: The container is likely to exist for only a short time
+ * before being destroyed. (For example, containers for
+ * multipart/x-mixed-replace image parts fall into this category.) If this
+ * flag is set, INIT_FLAG_DISCARDABLE and INIT_FLAG_DECODE_ONLY_ON_DRAW must
+ * not be set.
+ *
+ * INIT_FLAG_SYNC_LOAD: The container is being loaded synchronously, so
+ * it should avoid relying on async workers to get the container ready.
+ */
+ static const uint32_t INIT_FLAG_NONE = 0x0;
+ static const uint32_t INIT_FLAG_DISCARDABLE = 0x1;
+ static const uint32_t INIT_FLAG_DECODE_IMMEDIATELY = 0x2;
+ static const uint32_t INIT_FLAG_TRANSIENT = 0x4;
+ static const uint32_t INIT_FLAG_SYNC_LOAD = 0x8;
+
+ virtual already_AddRefed<ProgressTracker> GetProgressTracker() = 0;
+ virtual void SetProgressTracker(ProgressTracker* aProgressTracker) {}
+
+ /**
+ * The size, in bytes, occupied by the compressed source data of the image.
+ * If MallocSizeOf does not work on this platform, uses a fallback approach to
+ * ensure that something reasonable is always returned.
+ */
+ virtual size_t SizeOfSourceWithComputedFallback(
+ SizeOfState& aState) const = 0;
+
+ /**
+ * Collect an accounting of the memory occupied by the image's surfaces (which
+ * together make up its decoded data). Each surface is recorded as a separate
+ * SurfaceMemoryCounter, stored in @aCounters.
+ */
+ virtual void CollectSizeOfSurfaces(nsTArray<SurfaceMemoryCounter>& aCounters,
+ MallocSizeOf aMallocSizeOf) const = 0;
+
+ virtual void IncrementAnimationConsumers() = 0;
+ virtual void DecrementAnimationConsumers() = 0;
+#ifdef DEBUG
+ virtual uint32_t GetAnimationConsumers() = 0;
+#endif
+
+ /**
+ * Called from OnDataAvailable when the stream associated with the image has
+ * received new image data. The arguments are the same as OnDataAvailable's,
+ * but by separating this functionality into a different method we don't
+ * interfere with subclasses which wish to implement nsIStreamListener.
+ *
+ * Images should not do anything that could send out notifications until they
+ * have received their first OnImageDataAvailable notification; in
+ * particular, this means that instantiating decoders should be deferred
+ * until OnImageDataAvailable is called.
+ */
+ virtual nsresult OnImageDataAvailable(nsIRequest* aRequest,
+ nsIInputStream* aInStr,
+ uint64_t aSourceOffset,
+ uint32_t aCount) = 0;
+
+ /**
+ * Called from OnStopRequest when the image's underlying request completes.
+ *
+ * @param aRequest The completed request.
+ * @param aStatus A success or failure code.
+ * @param aLastPart Whether this is the final part of the underlying request.
+ */
+ virtual nsresult OnImageDataComplete(nsIRequest* aRequest, nsresult aStatus,
+ bool aLastPart) = 0;
+
+ /**
+ * Called when the SurfaceCache discards a surface belonging to this image.
+ */
+ virtual void OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) = 0;
+
+ virtual void SetInnerWindowID(uint64_t aInnerWindowId) = 0;
+ virtual uint64_t InnerWindowID() const = 0;
+
+ virtual bool HasError() = 0;
+ virtual void SetHasError() = 0;
+
+ virtual nsIURI* GetURI() const = 0;
+
+ NS_IMETHOD GetHotspotX(int32_t* aX) override {
+ *aX = 0;
+ return NS_OK;
+ }
+ NS_IMETHOD GetHotspotY(int32_t* aY) override {
+ *aY = 0;
+ return NS_OK;
+ }
+};
+
+class ImageResource : public Image {
+ public:
+ already_AddRefed<ProgressTracker> GetProgressTracker() override {
+ RefPtr<ProgressTracker> progressTracker = mProgressTracker;
+ MOZ_ASSERT(progressTracker);
+ return progressTracker.forget();
+ }
+
+ void SetProgressTracker(ProgressTracker* aProgressTracker) final {
+ MOZ_ASSERT(aProgressTracker);
+ MOZ_ASSERT(!mProgressTracker);
+ mProgressTracker = aProgressTracker;
+ }
+
+ virtual void IncrementAnimationConsumers() override;
+ virtual void DecrementAnimationConsumers() override;
+#ifdef DEBUG
+ virtual uint32_t GetAnimationConsumers() override {
+ return mAnimationConsumers;
+ }
+#endif
+
+ virtual void OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) override {}
+
+ virtual void SetInnerWindowID(uint64_t aInnerWindowId) override {
+ mInnerWindowId = aInnerWindowId;
+ }
+ virtual uint64_t InnerWindowID() const override { return mInnerWindowId; }
+
+ virtual bool HasError() override { return mError; }
+ virtual void SetHasError() override { mError = true; }
+
+ /*
+ * Returns a non-AddRefed pointer to the URI associated with this image.
+ * Illegal to use off-main-thread.
+ */
+ nsIURI* GetURI() const override { return mURI; }
+
+ /*
+ * Should be called by its subclasses after they populate @aCounters so that
+ * we can cross reference against any of our ImageContainers that contain
+ * surfaces not in the cache.
+ */
+ void CollectSizeOfSurfaces(nsTArray<SurfaceMemoryCounter>& aCounters,
+ MallocSizeOf aMallocSizeOf) const override;
+
+ ImageProviderId GetImageProviderId() const { return mProviderId; }
+
+ protected:
+ explicit ImageResource(nsIURI* aURI);
+ ~ImageResource();
+
+ bool GetSpecTruncatedTo1k(nsCString& aSpec) const;
+
+ // Shared functionality for implementors of imgIContainer. Every
+ // implementation of attribute animationMode should forward here.
+ nsresult GetAnimationModeInternal(uint16_t* aAnimationMode);
+ nsresult SetAnimationModeInternal(uint16_t aAnimationMode);
+
+ /**
+ * Helper for RequestRefresh.
+ *
+ * If we've had a "recent" refresh (i.e. if this image is being used in
+ * multiple documents & some other document *just* called RequestRefresh() on
+ * this image with a timestamp close to aTime), this method returns true.
+ *
+ * Otherwise, this method updates mLastRefreshTime to aTime & returns false.
+ */
+ bool HadRecentRefresh(const TimeStamp& aTime);
+
+ /**
+ * Decides whether animation should or should not be happening,
+ * and makes sure the right thing is being done.
+ */
+ virtual void EvaluateAnimation();
+
+ /**
+ * Extended by child classes, if they have additional
+ * conditions for being able to animate.
+ */
+ virtual bool ShouldAnimate() {
+ return mAnimationConsumers > 0 && mAnimationMode != kDontAnimMode;
+ }
+
+ virtual nsresult StartAnimation() = 0;
+ virtual nsresult StopAnimation() = 0;
+
+ void SendOnUnlockedDraw(uint32_t aFlags);
+
+#ifdef DEBUG
+ // Records the image drawing for startup performance testing.
+ void NotifyDrawingObservers();
+#endif
+
+ // Member data shared by all implementations of this abstract class
+ RefPtr<ProgressTracker> mProgressTracker;
+ nsCOMPtr<nsIURI> mURI;
+ TimeStamp mLastRefreshTime;
+ uint64_t mInnerWindowId;
+ uint32_t mAnimationConsumers;
+ uint16_t mAnimationMode; // Enum values in imgIContainer
+ bool mInitialized : 1; // Have we been initialized?
+ bool mAnimating : 1; // Are we currently animating?
+ bool mError : 1; // Error handling
+
+ class MOZ_RAII AutoProfilerImagePaintMarker {
+ public:
+ explicit AutoProfilerImagePaintMarker(ImageResource* self) {
+ if (self->mURI && profiler_thread_is_being_profiled_for_markers()) {
+ mStartTime = TimeStamp::Now();
+ static const size_t sMaxTruncatedLength = 1024;
+ mSpec = nsContentUtils::TruncatedURLForDisplay(self->mURI,
+ sMaxTruncatedLength);
+ }
+ }
+
+ ~AutoProfilerImagePaintMarker() {
+ if (!mSpec.IsEmpty()) {
+ PROFILER_MARKER_TEXT("Image Paint", GRAPHICS,
+ MarkerTiming::IntervalUntilNowFrom(mStartTime),
+ mSpec);
+ }
+ }
+
+ protected:
+ TimeStamp mStartTime;
+ nsAutoCString mSpec;
+ };
+
+ private:
+ ImageProviderId mProviderId;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_Image_h
diff --git a/image/ImageBlocker.cpp b/image/ImageBlocker.cpp
new file mode 100644
index 0000000000..eee07589f7
--- /dev/null
+++ b/image/ImageBlocker.cpp
@@ -0,0 +1,59 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageBlocker.h"
+#include "nsIPermissionManager.h"
+#include "nsContentUtils.h"
+#include "mozilla/StaticPrefs_permissions.h"
+#include "nsNetUtil.h"
+
+using namespace mozilla;
+using namespace mozilla::image;
+
+NS_IMPL_ISUPPORTS(ImageBlocker, nsIContentPolicy)
+
+NS_IMETHODIMP
+ImageBlocker::ShouldLoad(nsIURI* aContentLocation, nsILoadInfo* aLoadInfo,
+ const nsACString& aMimeGuess, int16_t* aShouldLoad) {
+ ExtContentPolicyType contentType = aLoadInfo->GetExternalContentPolicyType();
+
+ *aShouldLoad = nsIContentPolicy::ACCEPT;
+
+ if (!aContentLocation) {
+ // Bug 1720280: Ideally we should block the load, but to avoid a potential
+ // null pointer deref, we return early in this case. Please note that
+ // the ImageBlocker only applies about http/https loads anyway.
+ return NS_OK;
+ }
+
+ // we only want to check http, https
+ // for chrome:// and resources and others, no need to check.
+ nsAutoCString scheme;
+ aContentLocation->GetScheme(scheme);
+ if (!scheme.LowerCaseEqualsLiteral("http") &&
+ !scheme.LowerCaseEqualsLiteral("https")) {
+ return NS_OK;
+ }
+
+ // Block loading images depending on the permissions.default.image pref.
+ if ((contentType == ExtContentPolicy::TYPE_IMAGE ||
+ contentType == ExtContentPolicy::TYPE_IMAGESET) &&
+ StaticPrefs::permissions_default_image() ==
+ nsIPermissionManager::DENY_ACTION) {
+ NS_SetRequestBlockingReason(
+ aLoadInfo, nsILoadInfo::BLOCKING_REASON_CONTENT_POLICY_CONTENT_BLOCKED);
+ *aShouldLoad = nsIContentPolicy::REJECT_TYPE;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+ImageBlocker::ShouldProcess(nsIURI* aContentLocation, nsILoadInfo* aLoadInfo,
+ const nsACString& aMimeGuess,
+ int16_t* aShouldProcess) {
+ // We block images at load level already, so those should not end up here.
+ *aShouldProcess = nsIContentPolicy::ACCEPT;
+ return NS_OK;
+}
diff --git a/image/ImageBlocker.h b/image/ImageBlocker.h
new file mode 100644
index 0000000000..f5b03280be
--- /dev/null
+++ b/image/ImageBlocker.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_ImageBlocker_h
+#define mozilla_image_ImageBlocker_h
+
+#include "nsIContentPolicy.h"
+
+namespace mozilla {
+namespace image {
+
+#define IMAGEBLOCKER_CONTRACTID "@mozilla.org/image-blocker-content-policy;1"
+#define IMAGEBLOCKER_CID \
+ { /* f6fcd651-164b-4416-b001-9c8c393fd93b */ \
+ 0xf6fcd651, 0x164b, 0x4416, { \
+ 0xb0, 0x01, 0x9c, 0x8c, 0x39, 0x3f, 0xd9, 0x3b \
+ } \
+ }
+
+class ImageBlocker final : public nsIContentPolicy {
+ ~ImageBlocker() = default;
+
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSICONTENTPOLICY
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_ImageBlocker_h
diff --git a/image/ImageCacheKey.cpp b/image/ImageCacheKey.cpp
new file mode 100644
index 0000000000..7a5f78b70f
--- /dev/null
+++ b/image/ImageCacheKey.cpp
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageCacheKey.h"
+
+#include <utility>
+
+#include "mozilla/AntiTrackingUtils.h"
+#include "mozilla/HashFunctions.h"
+#include "mozilla/StorageAccess.h"
+#include "mozilla/StoragePrincipalHelper.h"
+#include "mozilla/Unused.h"
+#include "mozilla/dom/Document.h"
+#include "mozilla/dom/File.h"
+#include "mozilla/dom/ServiceWorkerManager.h"
+#include "mozilla/StaticPrefs_privacy.h"
+#include "mozilla/StorageAccess.h"
+#include "nsContentUtils.h"
+#include "nsHashKeys.h"
+#include "nsLayoutUtils.h"
+#include "nsPrintfCString.h"
+#include "nsString.h"
+
+namespace mozilla {
+
+using namespace dom;
+
+namespace image {
+
+ImageCacheKey::ImageCacheKey(nsIURI* aURI, CORSMode aCORSMode,
+ const OriginAttributes& aAttrs,
+ Document* aDocument)
+ : mURI(aURI),
+ mOriginAttributes(aAttrs),
+ mControlledDocument(GetSpecialCaseDocumentToken(aDocument)),
+ mIsolationKey(GetIsolationKey(aDocument, aURI)),
+ mCORSMode(aCORSMode) {}
+
+ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther)
+ : mURI(aOther.mURI),
+ mOriginAttributes(aOther.mOriginAttributes),
+ mControlledDocument(aOther.mControlledDocument),
+ mIsolationKey(aOther.mIsolationKey),
+ mHash(aOther.mHash),
+ mCORSMode(aOther.mCORSMode) {}
+
+ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther)
+ : mURI(std::move(aOther.mURI)),
+ mOriginAttributes(aOther.mOriginAttributes),
+ mControlledDocument(aOther.mControlledDocument),
+ mIsolationKey(aOther.mIsolationKey),
+ mHash(aOther.mHash),
+ mCORSMode(aOther.mCORSMode) {}
+
+bool ImageCacheKey::operator==(const ImageCacheKey& aOther) const {
+ // Don't share the image cache between a controlled document and anything
+ // else.
+ if (mControlledDocument != aOther.mControlledDocument) {
+ return false;
+ }
+ // Don't share the image cache between two top-level documents of different
+ // base domains.
+ if (!mIsolationKey.Equals(aOther.mIsolationKey,
+ nsCaseInsensitiveCStringComparator)) {
+ return false;
+ }
+ // The origin attributes always have to match.
+ if (mOriginAttributes != aOther.mOriginAttributes) {
+ return false;
+ }
+
+ if (mCORSMode != aOther.mCORSMode) {
+ return false;
+ }
+
+ // For non-blob URIs, compare the URIs.
+ bool equals = false;
+ nsresult rv = mURI->Equals(aOther.mURI, &equals);
+ return NS_SUCCEEDED(rv) && equals;
+}
+
+void ImageCacheKey::EnsureHash() const {
+ MOZ_ASSERT(mHash.isNothing());
+ PLDHashNumber hash = 0;
+
+ // Since we frequently call Hash() several times in a row on the same
+ // ImageCacheKey, as an optimization we compute our hash once and store it.
+
+ nsPrintfCString ptr("%p", mControlledDocument);
+ nsAutoCString suffix;
+ mOriginAttributes.CreateSuffix(suffix);
+
+ nsAutoCString spec;
+ Unused << mURI->GetSpec(spec);
+ hash = HashString(spec);
+
+ hash = AddToHash(hash, HashString(suffix), HashString(mIsolationKey),
+ HashString(ptr));
+ mHash.emplace(hash);
+}
+
+/* static */
+void* ImageCacheKey::GetSpecialCaseDocumentToken(Document* aDocument) {
+ // Cookie-averse documents can never have storage granted to them. Since they
+ // may not have inner windows, they would require special handling below, so
+ // just bail out early here.
+ if (!aDocument || aDocument->IsCookieAverse()) {
+ return nullptr;
+ }
+
+ // For controlled documents, we cast the pointer into a void* to avoid
+ // dereferencing it (since we only use it for comparisons).
+ RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
+ if (swm && aDocument->GetController().isSome()) {
+ return aDocument;
+ }
+
+ return nullptr;
+}
+
+/* static */
+nsCString ImageCacheKey::GetIsolationKey(Document* aDocument, nsIURI* aURI) {
+ if (!aDocument || !aDocument->GetInnerWindow()) {
+ return ""_ns;
+ }
+
+ // Network-state isolation
+ if (StaticPrefs::privacy_partition_network_state()) {
+ OriginAttributes oa;
+ StoragePrincipalHelper::GetOriginAttributesForNetworkState(aDocument, oa);
+
+ nsAutoCString suffix;
+ oa.CreateSuffix(suffix);
+
+ return std::move(suffix);
+ }
+
+ // If the window is 3rd party resource, let's see if first-party storage
+ // access is granted for this image.
+ if (AntiTrackingUtils::IsThirdPartyWindow(aDocument->GetInnerWindow(),
+ nullptr)) {
+ uint32_t rejectedReason = 0;
+ Unused << rejectedReason;
+ return StorageDisabledByAntiTracking(aDocument, aURI, rejectedReason)
+ ? aDocument->GetBaseDomain()
+ : ""_ns;
+ }
+
+ // Another scenario is if this image is a 3rd party resource loaded by a
+ // first party context. In this case, we should check if the nsIChannel has
+ // been marked as tracking resource, but we don't have the channel yet at
+ // this point. The best approach here is to be conservative: if we are sure
+ // that the permission is granted, let's return 0. Otherwise, let's make a
+ // unique image cache per the top-level document eTLD+1.
+ if (!ApproximateAllowAccessForWithoutChannel(aDocument->GetInnerWindow(),
+ aURI)) {
+ // If we are here, the image is a 3rd-party resource loaded by a first-party
+ // context. We can just use the document's base domain as the key because it
+ // should be the same as the top-level document's base domain.
+ return aDocument
+ ->GetBaseDomain(); // because we don't have anything better!
+ }
+
+ return ""_ns;
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/ImageCacheKey.h b/image/ImageCacheKey.h
new file mode 100644
index 0000000000..2be4493081
--- /dev/null
+++ b/image/ImageCacheKey.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * ImageCacheKey is the key type for the image cache (see imgLoader.h).
+ */
+
+#ifndef mozilla_image_src_ImageCacheKey_h
+#define mozilla_image_src_ImageCacheKey_h
+
+#include "mozilla/BasePrincipal.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/RefPtr.h"
+#include "PLDHashTable.h"
+
+class nsIURI;
+
+namespace mozilla {
+
+enum CORSMode : uint8_t;
+
+namespace image {
+
+/**
+ * An ImageLib cache entry key.
+ *
+ * We key the cache on the initial URI (before any redirects), with some
+ * canonicalization applied. See ComputeHash() for the details.
+ * Controlled documents do not share their cache entries with
+ * non-controlled documents, or other controlled documents.
+ */
+class ImageCacheKey final {
+ public:
+ ImageCacheKey(nsIURI*, CORSMode, const OriginAttributes&, dom::Document*);
+
+ ImageCacheKey(const ImageCacheKey& aOther);
+ ImageCacheKey(ImageCacheKey&& aOther);
+
+ bool operator==(const ImageCacheKey& aOther) const;
+ PLDHashNumber Hash() const {
+ if (MOZ_UNLIKELY(mHash.isNothing())) {
+ EnsureHash();
+ }
+ return mHash.value();
+ }
+
+ /// A weak pointer to the URI.
+ nsIURI* URI() const { return mURI; }
+
+ CORSMode GetCORSMode() const { return mCORSMode; }
+
+ const OriginAttributes& OriginAttributesRef() const {
+ return mOriginAttributes;
+ }
+
+ const nsCString& IsolationKeyRef() const { return mIsolationKey; }
+
+ /// A token indicating which service worker controlled document this entry
+ /// belongs to, if any.
+ void* ControlledDocument() const { return mControlledDocument; }
+
+ private:
+ // For ServiceWorker we need to use the document as
+ // token for the key. All those exceptions are handled by this method.
+ static void* GetSpecialCaseDocumentToken(dom::Document* aDocument);
+
+ // For anti-tracking we need to use an isolation key. It can be the suffix of
+ // the PatitionedPrincipal (see StoragePrincipalHelper.h) or the top-level
+ // document's base domain. This is handled by this method.
+ static nsCString GetIsolationKey(dom::Document* aDocument, nsIURI* aURI);
+
+ void EnsureHash() const;
+
+ nsCOMPtr<nsIURI> mURI;
+ const OriginAttributes mOriginAttributes;
+ void* mControlledDocument;
+ nsCString mIsolationKey;
+ mutable Maybe<PLDHashNumber> mHash;
+ const CORSMode mCORSMode;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_src_ImageCacheKey_h
diff --git a/image/ImageFactory.cpp b/image/ImageFactory.cpp
new file mode 100644
index 0000000000..27541634dc
--- /dev/null
+++ b/image/ImageFactory.cpp
@@ -0,0 +1,277 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageFactory.h"
+
+#include <algorithm>
+
+#include "mozilla/Likely.h"
+
+#include "nsIChannel.h"
+#include "nsIFileChannel.h"
+#include "nsIObserverService.h"
+#include "nsIFile.h"
+#include "nsMimeTypes.h"
+#include "nsIRequest.h"
+
+#include "MultipartImage.h"
+#include "RasterImage.h"
+#include "VectorImage.h"
+#include "Image.h"
+#include "nsMediaFragmentURIParser.h"
+#include "nsContentUtils.h"
+
+#include "mozilla/SchedulerGroup.h"
+#include "mozilla/StaticPrefs_image.h"
+#include "mozilla/ProfilerMarkers.h"
+
+namespace mozilla {
+namespace image {
+
+/*static*/
+void ImageFactory::Initialize() {}
+
+static uint32_t ComputeImageFlags(nsIURI* uri, const nsCString& aMimeType,
+ bool isMultiPart) {
+ // We default to the static globals.
+ bool isDiscardable = StaticPrefs::image_mem_discardable();
+ bool doDecodeImmediately = StaticPrefs::image_decode_immediately_enabled();
+
+ // We want UI to be as snappy as possible and not to flicker. Disable
+ // discarding for chrome URLS.
+ if (uri->SchemeIs("chrome")) {
+ isDiscardable = false;
+ }
+
+ // We don't want resources like the "loading" icon to be discardable either.
+ if (uri->SchemeIs("resource")) {
+ isDiscardable = false;
+ }
+
+ // For multipart/x-mixed-replace, we basically want a direct channel to the
+ // decoder. Disable everything for this case.
+ if (isMultiPart) {
+ isDiscardable = false;
+ }
+
+ // We have all the information we need.
+ uint32_t imageFlags = Image::INIT_FLAG_NONE;
+ if (isDiscardable) {
+ imageFlags |= Image::INIT_FLAG_DISCARDABLE;
+ }
+ if (doDecodeImmediately) {
+ imageFlags |= Image::INIT_FLAG_DECODE_IMMEDIATELY;
+ }
+ if (isMultiPart) {
+ imageFlags |= Image::INIT_FLAG_TRANSIENT;
+ }
+
+ // Synchronously decode metadata (including size) if we have a data URI since
+ // the data is immediately available.
+ if (uri->SchemeIs("data")) {
+ imageFlags |= Image::INIT_FLAG_SYNC_LOAD;
+ }
+
+ return imageFlags;
+}
+
+#ifdef DEBUG
+static void NotifyImageLoading(nsIURI* aURI) {
+ if (!NS_IsMainThread()) {
+ nsCOMPtr<nsIURI> uri(aURI);
+ nsCOMPtr<nsIRunnable> ev = NS_NewRunnableFunction(
+ "NotifyImageLoading", [uri]() -> void { NotifyImageLoading(uri); });
+ SchedulerGroup::Dispatch(TaskCategory::Other, ev.forget());
+ return;
+ }
+
+ nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+ NS_WARNING_ASSERTION(obs, "Can't get an observer service handle");
+ if (obs) {
+ nsAutoCString spec;
+ aURI->GetSpec(spec);
+ obs->NotifyObservers(nullptr, "image-loading",
+ NS_ConvertUTF8toUTF16(spec).get());
+ }
+}
+#endif
+
+/* static */
+already_AddRefed<Image> ImageFactory::CreateImage(
+ nsIRequest* aRequest, ProgressTracker* aProgressTracker,
+ const nsCString& aMimeType, nsIURI* aURI, bool aIsMultiPart,
+ uint64_t aInnerWindowId) {
+ // Compute the image's initialization flags.
+ uint32_t imageFlags = ComputeImageFlags(aURI, aMimeType, aIsMultiPart);
+
+#ifdef DEBUG
+ // Record the image load for startup performance testing.
+ if (aURI->SchemeIs("resource") || aURI->SchemeIs("chrome")) {
+ NotifyImageLoading(aURI);
+ }
+#endif
+
+ if (profiler_thread_is_being_profiled_for_markers()) {
+ static const size_t sMaxTruncatedLength = 1024;
+ PROFILER_MARKER_TEXT(
+ "Image Load", GRAPHICS, MarkerInnerWindowId(aInnerWindowId),
+ nsContentUtils::TruncatedURLForDisplay(aURI, sMaxTruncatedLength));
+ }
+
+ // Select the type of image to create based on MIME type.
+ if (aMimeType.EqualsLiteral(IMAGE_SVG_XML)) {
+ return CreateVectorImage(aRequest, aProgressTracker, aMimeType, aURI,
+ imageFlags, aInnerWindowId);
+ } else {
+ return CreateRasterImage(aRequest, aProgressTracker, aMimeType, aURI,
+ imageFlags, aInnerWindowId);
+ }
+}
+
+// Marks an image as having an error before returning it.
+template <typename T>
+static already_AddRefed<Image> BadImage(const char* aMessage,
+ RefPtr<T>& aImage) {
+ aImage->SetHasError();
+ return aImage.forget();
+}
+
+/* static */
+already_AddRefed<Image> ImageFactory::CreateAnonymousImage(
+ const nsCString& aMimeType, uint32_t aSizeHint /* = 0 */) {
+ nsresult rv;
+
+ RefPtr<RasterImage> newImage = new RasterImage();
+
+ RefPtr<ProgressTracker> newTracker = new ProgressTracker();
+ newTracker->SetImage(newImage);
+ newImage->SetProgressTracker(newTracker);
+
+ rv = newImage->Init(aMimeType.get(), Image::INIT_FLAG_SYNC_LOAD);
+ if (NS_FAILED(rv)) {
+ return BadImage("RasterImage::Init failed", newImage);
+ }
+
+ rv = newImage->SetSourceSizeHint(aSizeHint);
+ if (NS_FAILED(rv)) {
+ return BadImage("RasterImage::SetSourceSizeHint failed", newImage);
+ }
+
+ return newImage.forget();
+}
+
+/* static */
+already_AddRefed<MultipartImage> ImageFactory::CreateMultipartImage(
+ Image* aFirstPart, ProgressTracker* aProgressTracker) {
+ MOZ_ASSERT(aFirstPart);
+ MOZ_ASSERT(aProgressTracker);
+
+ RefPtr<MultipartImage> newImage = new MultipartImage(aFirstPart);
+ aProgressTracker->SetImage(newImage);
+ newImage->SetProgressTracker(aProgressTracker);
+
+ newImage->Init();
+
+ return newImage.forget();
+}
+
+int32_t SaturateToInt32(int64_t val) {
+ if (val > INT_MAX) {
+ return INT_MAX;
+ }
+ if (val < INT_MIN) {
+ return INT_MIN;
+ }
+
+ return static_cast<int32_t>(val);
+}
+
+uint32_t GetContentSize(nsIRequest* aRequest) {
+ nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
+ if (channel) {
+ int64_t size;
+ nsresult rv = channel->GetContentLength(&size);
+ if (NS_SUCCEEDED(rv)) {
+ return std::max(SaturateToInt32(size), 0);
+ }
+ }
+
+ // Use the file size as a size hint for file channels.
+ nsCOMPtr<nsIFileChannel> fileChannel(do_QueryInterface(aRequest));
+ if (fileChannel) {
+ nsCOMPtr<nsIFile> file;
+ nsresult rv = fileChannel->GetFile(getter_AddRefs(file));
+ if (NS_SUCCEEDED(rv)) {
+ int64_t filesize;
+ rv = file->GetFileSize(&filesize);
+ if (NS_SUCCEEDED(rv)) {
+ return std::max(SaturateToInt32(filesize), 0);
+ }
+ }
+ }
+
+ // Fallback - neither http nor file. We'll use dynamic allocation.
+ return 0;
+}
+
+/* static */
+already_AddRefed<Image> ImageFactory::CreateRasterImage(
+ nsIRequest* aRequest, ProgressTracker* aProgressTracker,
+ const nsCString& aMimeType, nsIURI* aURI, uint32_t aImageFlags,
+ uint64_t aInnerWindowId) {
+ MOZ_ASSERT(aProgressTracker);
+
+ nsresult rv;
+
+ RefPtr<RasterImage> newImage = new RasterImage(aURI);
+ aProgressTracker->SetImage(newImage);
+ newImage->SetProgressTracker(aProgressTracker);
+
+ rv = newImage->Init(aMimeType.get(), aImageFlags);
+ if (NS_FAILED(rv)) {
+ return BadImage("RasterImage::Init failed", newImage);
+ }
+
+ newImage->SetInnerWindowID(aInnerWindowId);
+
+ rv = newImage->SetSourceSizeHint(GetContentSize(aRequest));
+ if (NS_FAILED(rv)) {
+ return BadImage("RasterImage::SetSourceSizeHint failed", newImage);
+ }
+
+ return newImage.forget();
+}
+
+/* static */
+already_AddRefed<Image> ImageFactory::CreateVectorImage(
+ nsIRequest* aRequest, ProgressTracker* aProgressTracker,
+ const nsCString& aMimeType, nsIURI* aURI, uint32_t aImageFlags,
+ uint64_t aInnerWindowId) {
+ MOZ_ASSERT(aProgressTracker);
+
+ nsresult rv;
+
+ RefPtr<VectorImage> newImage = new VectorImage(aURI);
+ aProgressTracker->SetImage(newImage);
+ newImage->SetProgressTracker(aProgressTracker);
+
+ rv = newImage->Init(aMimeType.get(), aImageFlags);
+ if (NS_FAILED(rv)) {
+ return BadImage("VectorImage::Init failed", newImage);
+ }
+
+ newImage->SetInnerWindowID(aInnerWindowId);
+
+ rv = newImage->OnStartRequest(aRequest);
+ if (NS_FAILED(rv)) {
+ return BadImage("VectorImage::OnStartRequest failed", newImage);
+ }
+
+ return newImage.forget();
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/ImageFactory.h b/image/ImageFactory.h
new file mode 100644
index 0000000000..1f9b677739
--- /dev/null
+++ b/image/ImageFactory.h
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_ImageFactory_h
+#define mozilla_image_ImageFactory_h
+
+#include "nsCOMPtr.h"
+#include "nsProxyRelease.h"
+#include "nsStringFwd.h"
+
+class nsIRequest;
+class nsIURI;
+
+namespace mozilla {
+namespace image {
+
+class Image;
+class MultipartImage;
+class ProgressTracker;
+
+class ImageFactory {
+ public:
+ /**
+ * Registers vars with Preferences. Should only be called on the main thread.
+ */
+ static void Initialize();
+
+ /**
+ * Creates a new image with the given properties.
+ * Can be called on or off the main thread.
+ *
+ * @param aRequest The associated request.
+ * @param aProgressTracker A status tracker for the image to use.
+ * @param aMimeType The mimetype of the image.
+ * @param aURI The URI of the image.
+ * @param aIsMultiPart Whether the image is part of a multipart request.
+ * @param aInnerWindowId The window this image belongs to.
+ */
+ static already_AddRefed<Image> CreateImage(nsIRequest* aRequest,
+ ProgressTracker* aProgressTracker,
+ const nsCString& aMimeType,
+ nsIURI* aURI, bool aIsMultiPart,
+ uint64_t aInnerWindowId);
+ /**
+ * Creates a new image which isn't associated with a URI or loaded through
+ * the usual image loading mechanism.
+ *
+ * @param aMimeType The mimetype of the image.
+ * @param aSizeHint The length of the source data for the image.
+ */
+ static already_AddRefed<Image> CreateAnonymousImage(
+ const nsCString& aMimeType, uint32_t aSizeHint = 0);
+
+ /**
+ * Creates a new multipart/x-mixed-replace image wrapper, and initializes it
+ * with the first part. Subsequent parts should be passed to the existing
+ * MultipartImage via MultipartImage::BeginTransitionToPart().
+ *
+ * @param aFirstPart An image containing the first part of the multipart
+ * stream.
+ * @param aProgressTracker A progress tracker for the multipart image.
+ */
+ static already_AddRefed<MultipartImage> CreateMultipartImage(
+ Image* aFirstPart, ProgressTracker* aProgressTracker);
+
+ private:
+ // Factory functions that create specific types of image containers.
+ static already_AddRefed<Image> CreateRasterImage(
+ nsIRequest* aRequest, ProgressTracker* aProgressTracker,
+ const nsCString& aMimeType, nsIURI* aURI, uint32_t aImageFlags,
+ uint64_t aInnerWindowId);
+
+ static already_AddRefed<Image> CreateVectorImage(
+ nsIRequest* aRequest, ProgressTracker* aProgressTracker,
+ const nsCString& aMimeType, nsIURI* aURI, uint32_t aImageFlags,
+ uint64_t aInnerWindowId);
+
+ // This is a static factory class, so disallow instantiation.
+ virtual ~ImageFactory() = 0;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_ImageFactory_h
diff --git a/image/ImageLogging.h b/image/ImageLogging.h
new file mode 100644
index 0000000000..c36f4e8dbd
--- /dev/null
+++ b/image/ImageLogging.h
@@ -0,0 +1,185 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_ImageLogging_h
+#define mozilla_image_ImageLogging_h
+
+#include "mozilla/Logging.h"
+#include "Image.h"
+#include "nsIURI.h"
+#include "prinrval.h"
+
+static mozilla::LazyLogModule gImgLog("imgRequest");
+
+#define GIVE_ME_MS_NOW() PR_IntervalToMilliseconds(PR_IntervalNow())
+
+using mozilla::LogLevel;
+
+class LogScope {
+ public:
+ LogScope(mozilla::LogModule* aLog, void* aFrom, const char* aFunc)
+ : mLog(aLog), mFrom(aFrom), mFunc(aFunc) {
+ MOZ_LOG(mLog, LogLevel::Debug,
+ ("%d [this=%p] %s {ENTER}\n", GIVE_ME_MS_NOW(), mFrom, mFunc));
+ }
+
+ /* const char * constructor */
+ LogScope(mozilla::LogModule* aLog, void* from, const char* fn,
+ const char* paramName, const char* paramValue)
+ : mLog(aLog), mFrom(from), mFunc(fn) {
+ MOZ_LOG(mLog, LogLevel::Debug,
+ ("%d [this=%p] %s (%s=\"%s\") {ENTER}\n", GIVE_ME_MS_NOW(), mFrom,
+ mFunc, paramName, paramValue));
+ }
+
+ /* void ptr constructor */
+ LogScope(mozilla::LogModule* aLog, void* from, const char* fn,
+ const char* paramName, const void* paramValue)
+ : mLog(aLog), mFrom(from), mFunc(fn) {
+ MOZ_LOG(mLog, LogLevel::Debug,
+ ("%d [this=%p] %s (%s=%p) {ENTER}\n", GIVE_ME_MS_NOW(), mFrom,
+ mFunc, paramName, paramValue));
+ }
+
+ /* int32_t constructor */
+ LogScope(mozilla::LogModule* aLog, void* from, const char* fn,
+ const char* paramName, int32_t paramValue)
+ : mLog(aLog), mFrom(from), mFunc(fn) {
+ MOZ_LOG(mLog, LogLevel::Debug,
+ ("%d [this=%p] %s (%s=\"%d\") {ENTER}\n", GIVE_ME_MS_NOW(), mFrom,
+ mFunc, paramName, paramValue));
+ }
+
+ /* uint32_t constructor */
+ LogScope(mozilla::LogModule* aLog, void* from, const char* fn,
+ const char* paramName, uint32_t paramValue)
+ : mLog(aLog), mFrom(from), mFunc(fn) {
+ MOZ_LOG(mLog, LogLevel::Debug,
+ ("%d [this=%p] %s (%s=\"%d\") {ENTER}\n", GIVE_ME_MS_NOW(), mFrom,
+ mFunc, paramName, paramValue));
+ }
+
+ /* nsIURI constructor */
+ LogScope(mozilla::LogModule* aLog, void* from, const char* fn,
+ const char* paramName, nsIURI* aURI)
+ : mLog(aLog), mFrom(from), mFunc(fn) {
+ if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) {
+ static const size_t sMaxTruncatedLength = 1024;
+ nsAutoCString spec("<unknown>");
+ if (aURI) {
+ aURI->GetSpec(spec);
+ if (spec.Length() >= sMaxTruncatedLength) {
+ spec.Truncate(sMaxTruncatedLength);
+ }
+ }
+ MOZ_LOG(aLog, LogLevel::Debug,
+ ("%d [this=%p] %s (%s=\"%s\") {ENTER}\n", GIVE_ME_MS_NOW(), from,
+ fn, paramName, spec.get()));
+ }
+ }
+
+ /* Image constructor */
+ LogScope(mozilla::LogModule* aLog, void* from, const char* fn,
+ const char* paramName, mozilla::image::Image* aImage)
+ : LogScope(aLog, from, fn, paramName,
+ aImage ? aImage->GetURI() : nullptr) {}
+
+ ~LogScope() {
+ MOZ_LOG(mLog, LogLevel::Debug,
+ ("%d [this=%p] %s {EXIT}\n", GIVE_ME_MS_NOW(), mFrom, mFunc));
+ }
+
+ private:
+ mozilla::LogModule* mLog;
+ void* mFrom;
+ const char* mFunc;
+};
+
+class LogFunc {
+ public:
+ LogFunc(mozilla::LogModule* aLog, void* from, const char* fn) {
+ MOZ_LOG(aLog, LogLevel::Debug,
+ ("%d [this=%p] %s\n", GIVE_ME_MS_NOW(), from, fn));
+ }
+
+ LogFunc(mozilla::LogModule* aLog, void* from, const char* fn,
+ const char* paramName, const char* paramValue) {
+ MOZ_LOG(aLog, LogLevel::Debug,
+ ("%d [this=%p] %s (%s=\"%s\")\n", GIVE_ME_MS_NOW(), from, fn,
+ paramName, paramValue));
+ }
+
+ LogFunc(mozilla::LogModule* aLog, void* from, const char* fn,
+ const char* paramName, const void* paramValue) {
+ MOZ_LOG(aLog, LogLevel::Debug,
+ ("%d [this=%p] %s (%s=\"%p\")\n", GIVE_ME_MS_NOW(), from, fn,
+ paramName, paramValue));
+ }
+
+ LogFunc(mozilla::LogModule* aLog, void* from, const char* fn,
+ const char* paramName, uint32_t paramValue) {
+ MOZ_LOG(aLog, LogLevel::Debug,
+ ("%d [this=%p] %s (%s=\"%d\")\n", GIVE_ME_MS_NOW(), from, fn,
+ paramName, paramValue));
+ }
+
+ LogFunc(mozilla::LogModule* aLog, void* from, const char* fn,
+ const char* paramName, nsIURI* aURI) {
+ if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) {
+ static const size_t sMaxTruncatedLength = 1024;
+ nsAutoCString spec("<unknown>");
+ if (aURI) {
+ aURI->GetSpec(spec);
+ if (spec.Length() >= sMaxTruncatedLength) {
+ spec.Truncate(sMaxTruncatedLength);
+ }
+ }
+ MOZ_LOG(aLog, LogLevel::Debug,
+ ("%d [this=%p] %s (%s=\"%s\")\n", GIVE_ME_MS_NOW(), from, fn,
+ paramName, spec.get()));
+ }
+ }
+
+ LogFunc(mozilla::LogModule* aLog, void* from, const char* fn,
+ const char* paramName, mozilla::image::Image* aImage)
+ : LogFunc(aLog, from, fn, paramName,
+ aImage ? aImage->GetURI() : nullptr) {}
+};
+
+class LogMessage {
+ public:
+ LogMessage(mozilla::LogModule* aLog, void* from, const char* fn,
+ const char* msg) {
+ MOZ_LOG(aLog, LogLevel::Debug,
+ ("%d [this=%p] %s -- %s\n", GIVE_ME_MS_NOW(), from, fn, msg));
+ }
+};
+
+#define LOG_SCOPE_APPEND_LINE_NUMBER_PASTE(id, line) id##line
+#define LOG_SCOPE_APPEND_LINE_NUMBER_EXPAND(id, line) \
+ LOG_SCOPE_APPEND_LINE_NUMBER_PASTE(id, line)
+#define LOG_SCOPE_APPEND_LINE_NUMBER(id) \
+ LOG_SCOPE_APPEND_LINE_NUMBER_EXPAND(id, __LINE__)
+
+#define LOG_SCOPE(l, s) \
+ LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR)(l, this, s)
+
+#define LOG_SCOPE_WITH_PARAM(l, s, pn, pv) \
+ LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR)(l, this, s, pn, pv)
+
+#define LOG_FUNC(l, s) LogFunc(l, this, s)
+
+#define LOG_FUNC_WITH_PARAM(l, s, pn, pv) LogFunc(l, this, s, pn, pv)
+
+#define LOG_STATIC_FUNC(l, s) LogFunc(l, nullptr, s)
+
+#define LOG_STATIC_FUNC_WITH_PARAM(l, s, pn, pv) LogFunc(l, nullptr, s, pn, pv)
+
+#define LOG_MSG(l, s, m) LogMessage(l, this, s, m)
+
+#define LOG_MSG_WITH_PARAM LOG_FUNC_WITH_PARAM
+
+#endif // mozilla_image_ImageLogging_h
diff --git a/image/ImageMemoryReporter.cpp b/image/ImageMemoryReporter.cpp
new file mode 100644
index 0000000000..0afb890d00
--- /dev/null
+++ b/image/ImageMemoryReporter.cpp
@@ -0,0 +1,185 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageMemoryReporter.h"
+#include "Image.h"
+#include "base/process_util.h"
+#include "mozilla/layers/SharedSurfacesParent.h"
+#include "mozilla/StaticPrefs_image.h"
+#include "nsIMemoryReporter.h"
+#include "nsISupportsImpl.h"
+
+namespace mozilla {
+namespace image {
+
+ImageMemoryReporter::WebRenderReporter* ImageMemoryReporter::sWrReporter;
+
+class ImageMemoryReporter::WebRenderReporter final : public nsIMemoryReporter {
+ public:
+ NS_DECL_ISUPPORTS
+
+ WebRenderReporter() {}
+
+ NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
+ nsISupports* aData, bool aAnonymize) override {
+ layers::SharedSurfacesMemoryReport report;
+ layers::SharedSurfacesParent::AccumulateMemoryReport(report);
+ ReportSharedSurfaces(aHandleReport, aData, /* aIsForCompositor */ true,
+ report);
+ return NS_OK;
+ }
+
+ private:
+ virtual ~WebRenderReporter() {}
+};
+
+NS_IMPL_ISUPPORTS(ImageMemoryReporter::WebRenderReporter, nsIMemoryReporter)
+
+/* static */
+void ImageMemoryReporter::InitForWebRender() {
+ MOZ_ASSERT(XRE_IsParentProcess() || XRE_IsGPUProcess());
+ if (!sWrReporter) {
+ sWrReporter = new WebRenderReporter();
+ RegisterStrongMemoryReporter(sWrReporter);
+ }
+}
+
+/* static */
+void ImageMemoryReporter::ShutdownForWebRender() {
+ MOZ_ASSERT(XRE_IsParentProcess() || XRE_IsGPUProcess());
+ if (sWrReporter) {
+ UnregisterStrongMemoryReporter(sWrReporter);
+ sWrReporter = nullptr;
+ }
+}
+
+/* static */
+void ImageMemoryReporter::ReportSharedSurfaces(
+ nsIHandleReportCallback* aHandleReport, nsISupports* aData,
+ const layers::SharedSurfacesMemoryReport& aSharedSurfaces) {
+ ReportSharedSurfaces(aHandleReport, aData,
+ /* aIsForCompositor */ false, aSharedSurfaces);
+}
+
+/* static */
+void ImageMemoryReporter::ReportSharedSurfaces(
+ nsIHandleReportCallback* aHandleReport, nsISupports* aData,
+ bool aIsForCompositor,
+ const layers::SharedSurfacesMemoryReport& aSharedSurfaces) {
+ MOZ_ASSERT_IF(aIsForCompositor, XRE_IsParentProcess() || XRE_IsGPUProcess());
+ MOZ_ASSERT_IF(!aIsForCompositor,
+ XRE_IsParentProcess() || XRE_IsContentProcess());
+
+ for (auto i = aSharedSurfaces.mSurfaces.begin();
+ i != aSharedSurfaces.mSurfaces.end(); ++i) {
+ ReportSharedSurface(aHandleReport, aData, aIsForCompositor, i->first,
+ i->second);
+ }
+}
+
+/* static */
+void ImageMemoryReporter::ReportSharedSurface(
+ nsIHandleReportCallback* aHandleReport, nsISupports* aData,
+ bool aIsForCompositor, uint64_t aExternalId,
+ const layers::SharedSurfacesMemoryReport::SurfaceEntry& aEntry) {
+ nsAutoCString path;
+ if (aIsForCompositor) {
+ path.AppendLiteral("gfx/webrender/images/mapped_from_owner/");
+ } else {
+ path.AppendLiteral("gfx/webrender/images/owner_cache_missing/");
+ }
+
+ if (aIsForCompositor) {
+ path.AppendLiteral("pid=");
+ path.AppendInt(uint32_t(aEntry.mCreatorPid));
+ path.AppendLiteral("/");
+ }
+
+ if (StaticPrefs::image_mem_debug_reporting()) {
+ path.AppendInt(aExternalId, 16);
+ path.AppendLiteral("/");
+ }
+
+ path.AppendLiteral("image(");
+ path.AppendInt(aEntry.mSize.width);
+ path.AppendLiteral("x");
+ path.AppendInt(aEntry.mSize.height);
+ path.AppendLiteral(", compositor_ref:");
+ path.AppendInt(aEntry.mConsumers);
+ path.AppendLiteral(", creator_ref:");
+ path.AppendInt(aEntry.mCreatorRef);
+ path.AppendLiteral(")/decoded-");
+
+ size_t surfaceSize = mozilla::ipc::SharedMemory::PageAlignedSize(
+ aEntry.mSize.height * aEntry.mStride);
+
+ // If this memory has already been reported elsewhere (e.g. as part of our
+ // explicit section in the surface cache), we don't want report it again as
+ // KIND_NONHEAP and have it counted again. The paths must be different if the
+ // kinds are different to avoid problems when diffing memory reports.
+ bool sameProcess = aEntry.mCreatorPid == base::GetCurrentProcId();
+ int32_t kind;
+ if (aIsForCompositor && !sameProcess) {
+ path.AppendLiteral("nonheap");
+ kind = nsIMemoryReporter::KIND_NONHEAP;
+ } else {
+ path.AppendLiteral("other");
+ kind = nsIMemoryReporter::KIND_OTHER;
+ }
+
+ constexpr auto desc = "Decoded image data stored in shared memory."_ns;
+ aHandleReport->Callback(""_ns, path, kind, nsIMemoryReporter::UNITS_BYTES,
+ surfaceSize, desc, aData);
+}
+
+/* static */
+void ImageMemoryReporter::AppendSharedSurfacePrefix(
+ nsACString& aPathPrefix, const SurfaceMemoryCounter& aCounter,
+ layers::SharedSurfacesMemoryReport& aSharedSurfaces) {
+ uint64_t extId = aCounter.Values().ExternalId();
+ if (extId) {
+ auto gpuEntry = aSharedSurfaces.mSurfaces.find(extId);
+
+ if (StaticPrefs::image_mem_debug_reporting()) {
+ aPathPrefix.AppendLiteral(", external_id:");
+ aPathPrefix.AppendInt(extId, 16);
+ if (gpuEntry != aSharedSurfaces.mSurfaces.end()) {
+ aPathPrefix.AppendLiteral(", compositor_ref:");
+ aPathPrefix.AppendInt(gpuEntry->second.mConsumers);
+ } else {
+ aPathPrefix.AppendLiteral(", compositor_ref:missing");
+ }
+ }
+
+ if (gpuEntry != aSharedSurfaces.mSurfaces.end()) {
+ MOZ_ASSERT(gpuEntry->second.mCreatorRef);
+ aSharedSurfaces.mSurfaces.erase(gpuEntry);
+ }
+ }
+}
+
+/* static */
+void ImageMemoryReporter::TrimSharedSurfaces(
+ const ImageMemoryCounter& aCounter,
+ layers::SharedSurfacesMemoryReport& aSharedSurfaces) {
+ if (aSharedSurfaces.mSurfaces.empty()) {
+ return;
+ }
+
+ for (const SurfaceMemoryCounter& counter : aCounter.Surfaces()) {
+ uint64_t extId = counter.Values().ExternalId();
+ if (extId) {
+ auto gpuEntry = aSharedSurfaces.mSurfaces.find(extId);
+ if (gpuEntry != aSharedSurfaces.mSurfaces.end()) {
+ MOZ_ASSERT(gpuEntry->second.mCreatorRef);
+ aSharedSurfaces.mSurfaces.erase(gpuEntry);
+ }
+ }
+ }
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/ImageMemoryReporter.h b/image/ImageMemoryReporter.h
new file mode 100644
index 0000000000..ab7d55c46d
--- /dev/null
+++ b/image/ImageMemoryReporter.h
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_ImageMemoryReporter_h
+#define mozilla_image_ImageMemoryReporter_h
+
+#include <cstdint>
+#include "nsString.h"
+#include "mozilla/layers/SharedSurfacesMemoryReport.h"
+
+class nsISupports;
+class nsIHandleReportCallback;
+
+namespace mozilla {
+namespace image {
+struct ImageMemoryCounter;
+struct SurfaceMemoryCounter;
+
+class ImageMemoryReporter final {
+ public:
+ /**
+ * Initializes image related memory reporting in the compositor process when
+ * using WebRender.
+ */
+ static void InitForWebRender();
+
+ /**
+ * Tears down image related memory reporting in the compositor process when
+ * using WebRender.
+ */
+ static void ShutdownForWebRender();
+
+ /**
+ * Report all remaining entries in the shared surface's memory report. This
+ * should be used by the content or main process to allow reporting any
+ * entries that is was unable to cross reference with the local surface cache.
+ * These are candidates for having been leaked. This should be used in
+ * conjunction with AppendSharedSurfacePrefix and/or TrimSharedSurfaces to
+ * produce the expected result.
+ */
+ static void ReportSharedSurfaces(
+ nsIHandleReportCallback* aHandleReport, nsISupports* aData,
+ const layers::SharedSurfacesMemoryReport& aSharedSurfaces);
+
+ /**
+ * Adjust the path prefix for a surface to include any additional metadata for
+ * the shared surface, if any. It will also remove any corresponding entries
+ * in the given memory report.
+ */
+ static void AppendSharedSurfacePrefix(
+ nsACString& aPathPrefix, const SurfaceMemoryCounter& aCounter,
+ layers::SharedSurfacesMemoryReport& aSharedSurfaces);
+
+ /**
+ * Remove all entries in the memory report for the given set of surfaces for
+ * an image. This is useful when we aren't reporting on a particular image
+ * because it isn't notable.
+ */
+ static void TrimSharedSurfaces(
+ const ImageMemoryCounter& aCounter,
+ layers::SharedSurfacesMemoryReport& aSharedSurfaces);
+
+ private:
+ /**
+ * Report all remaining entries in the shared surface's memory report.
+ *
+ * aIsForCompositor controls how to interpret what remains in the report. If
+ * true, this should mirror exactly what is currently in
+ * SharedSurfacesParent's cache. This will report entries that are currently
+ * mapped into the compositor process. If false, then we are in a content or
+ * main process, and it should have removed entries that also exist in its
+ * local surface cache -- thus any remaining entries are those that are
+ * candidates for leaks.
+ */
+ static void ReportSharedSurfaces(
+ nsIHandleReportCallback* aHandleReport, nsISupports* aData,
+ bool aIsForCompositor,
+ const layers::SharedSurfacesMemoryReport& aSharedSurfaces);
+
+ static void ReportSharedSurface(
+ nsIHandleReportCallback* aHandleReport, nsISupports* aData,
+ bool aIsForCompositor, uint64_t aExternalId,
+ const layers::SharedSurfacesMemoryReport::SurfaceEntry& aEntry);
+
+ class WebRenderReporter;
+ static WebRenderReporter* sWrReporter;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_ImageMemoryReporter_h
diff --git a/image/ImageMetadata.h b/image/ImageMetadata.h
new file mode 100644
index 0000000000..0648812339
--- /dev/null
+++ b/image/ImageMetadata.h
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_ImageMetadata_h
+#define mozilla_image_ImageMetadata_h
+
+#include <stdint.h>
+#include <utility>
+#include "FrameTimeout.h"
+#include "Orientation.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/gfx/Rect.h"
+#include "mozilla/image/Resolution.h"
+#include "nsSize.h"
+#include "nsTArray.h"
+
+namespace mozilla::image {
+
+// The metadata about an image that decoders accumulate as they decode.
+class ImageMetadata {
+ public:
+ ImageMetadata() = default;
+
+ void SetHotspot(uint16_t aHotspotX, uint16_t aHotspotY) {
+ mHotspot = Some(gfx::IntPoint(aHotspotX, aHotspotY));
+ }
+ gfx::IntPoint GetHotspot() const { return *mHotspot; }
+ bool HasHotspot() const { return mHotspot.isSome(); }
+
+ void SetLoopCount(int32_t loopcount) { mLoopCount = loopcount; }
+ int32_t GetLoopCount() const { return mLoopCount; }
+
+ void SetLoopLength(FrameTimeout aLength) { mLoopLength = Some(aLength); }
+ FrameTimeout GetLoopLength() const { return *mLoopLength; }
+ bool HasLoopLength() const { return mLoopLength.isSome(); }
+
+ void SetFirstFrameTimeout(FrameTimeout aTimeout) {
+ mFirstFrameTimeout = aTimeout;
+ }
+ FrameTimeout GetFirstFrameTimeout() const { return mFirstFrameTimeout; }
+
+ void SetFirstFrameRefreshArea(const gfx::IntRect& aRefreshArea) {
+ mFirstFrameRefreshArea = Some(aRefreshArea);
+ }
+ gfx::IntRect GetFirstFrameRefreshArea() const {
+ return *mFirstFrameRefreshArea;
+ }
+ bool HasFirstFrameRefreshArea() const {
+ return mFirstFrameRefreshArea.isSome();
+ }
+
+ void SetSize(int32_t aWidth, int32_t aHeight, Orientation aOrientation,
+ Resolution aResolution) {
+ if (!HasSize()) {
+ mSize.emplace(
+ aOrientation.ToOriented(UnorientedIntSize(aWidth, aHeight)));
+ mOrientation.emplace(aOrientation);
+ mResolution = aResolution;
+ }
+ }
+ OrientedIntSize GetSize() const { return *mSize; }
+ bool HasSize() const { return mSize.isSome(); }
+
+ void AddNativeSize(const OrientedIntSize& aSize) {
+ mNativeSizes.AppendElement(aSize);
+ }
+
+ Resolution GetResolution() const { return mResolution; }
+
+ const nsTArray<OrientedIntSize>& GetNativeSizes() const {
+ return mNativeSizes;
+ }
+
+ Orientation GetOrientation() const { return *mOrientation; }
+ bool HasOrientation() const { return mOrientation.isSome(); }
+
+ void SetHasAnimation() { mHasAnimation = true; }
+ bool HasAnimation() const { return mHasAnimation; }
+
+ private:
+ /// The hotspot found on cursors, if present.
+ Maybe<gfx::IntPoint> mHotspot;
+
+ /// The loop count for animated images, or -1 for infinite loop.
+ int32_t mLoopCount = -1;
+
+ /// The resolution of the image in dppx.
+ Resolution mResolution;
+
+ // The total length of a single loop through an animated image.
+ Maybe<FrameTimeout> mLoopLength;
+
+ /// The timeout of an animated image's first frame.
+ FrameTimeout mFirstFrameTimeout = FrameTimeout::Forever();
+
+ // The area of the image that needs to be invalidated when the animation
+ // loops.
+ Maybe<gfx::IntRect> mFirstFrameRefreshArea;
+
+ Maybe<OrientedIntSize> mSize;
+ Maybe<Orientation> mOrientation;
+
+ // Sizes the image can natively decode to.
+ CopyableTArray<OrientedIntSize> mNativeSizes;
+
+ bool mHasAnimation = false;
+};
+
+} // namespace mozilla::image
+
+#endif // mozilla_image_ImageMetadata_h
diff --git a/image/ImageOps.cpp b/image/ImageOps.cpp
new file mode 100644
index 0000000000..875dc7b985
--- /dev/null
+++ b/image/ImageOps.cpp
@@ -0,0 +1,248 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageOps.h"
+
+#include "ClippedImage.h"
+#include "Decoder.h"
+#include "DecoderFactory.h"
+#include "DynamicImage.h"
+#include "FrozenImage.h"
+#include "IDecodingTask.h"
+#include "Image.h"
+#include "ImageMetadata.h"
+#include "imgIContainer.h"
+#include "mozilla/gfx/2D.h"
+#include "nsNetUtil.h" // for NS_NewBufferedInputStream
+#include "nsStreamUtils.h"
+#include "OrientedImage.h"
+#include "SourceBuffer.h"
+
+using namespace mozilla::gfx;
+
+namespace mozilla::image {
+
+/* static */
+already_AddRefed<Image> ImageOps::Freeze(Image* aImage) {
+ RefPtr<Image> frozenImage = new FrozenImage(aImage);
+ return frozenImage.forget();
+}
+
+/* static */
+already_AddRefed<imgIContainer> ImageOps::Freeze(imgIContainer* aImage) {
+ nsCOMPtr<imgIContainer> frozenImage =
+ new FrozenImage(static_cast<Image*>(aImage));
+ return frozenImage.forget();
+}
+
+/* static */
+already_AddRefed<Image> ImageOps::Clip(Image* aImage, nsIntRect aClip,
+ const Maybe<nsSize>& aSVGViewportSize) {
+ RefPtr<Image> clippedImage =
+ new ClippedImage(aImage, aClip, aSVGViewportSize);
+ return clippedImage.forget();
+}
+
+/* static */
+already_AddRefed<imgIContainer> ImageOps::Clip(
+ imgIContainer* aImage, nsIntRect aClip,
+ const Maybe<nsSize>& aSVGViewportSize) {
+ nsCOMPtr<imgIContainer> clippedImage =
+ new ClippedImage(static_cast<Image*>(aImage), aClip, aSVGViewportSize);
+ return clippedImage.forget();
+}
+
+/* static */
+already_AddRefed<Image> ImageOps::Orient(Image* aImage,
+ Orientation aOrientation) {
+ if (aOrientation.IsIdentity()) {
+ return do_AddRef(aImage);
+ }
+ RefPtr<Image> image = new OrientedImage(aImage, aOrientation);
+ return image.forget();
+}
+
+/* static */
+already_AddRefed<imgIContainer> ImageOps::Orient(imgIContainer* aImage,
+ Orientation aOrientation) {
+ return Orient(static_cast<Image*>(aImage), aOrientation);
+}
+
+/* static */
+already_AddRefed<imgIContainer> ImageOps::Unorient(imgIContainer* aImage) {
+ return Orient(aImage, aImage->GetOrientation().Reversed());
+}
+
+/* static */
+already_AddRefed<imgIContainer> ImageOps::CreateFromDrawable(
+ gfxDrawable* aDrawable) {
+ nsCOMPtr<imgIContainer> drawableImage = new DynamicImage(aDrawable);
+ return drawableImage.forget();
+}
+
+class ImageOps::ImageBufferImpl final : public ImageOps::ImageBuffer {
+ public:
+ explicit ImageBufferImpl(already_AddRefed<SourceBuffer> aSourceBuffer)
+ : mSourceBuffer(aSourceBuffer) {}
+
+ protected:
+ ~ImageBufferImpl() override {}
+
+ already_AddRefed<SourceBuffer> GetSourceBuffer() const override {
+ RefPtr<SourceBuffer> sourceBuffer = mSourceBuffer;
+ return sourceBuffer.forget();
+ }
+
+ private:
+ RefPtr<SourceBuffer> mSourceBuffer;
+};
+
+/* static */ already_AddRefed<ImageOps::ImageBuffer>
+ImageOps::CreateImageBuffer(already_AddRefed<nsIInputStream> aInputStream) {
+ nsCOMPtr<nsIInputStream> inputStream = std::move(aInputStream);
+ MOZ_ASSERT(inputStream);
+
+ nsresult rv;
+
+ // Prepare the input stream.
+ if (!NS_InputStreamIsBuffered(inputStream)) {
+ nsCOMPtr<nsIInputStream> bufStream;
+ rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream),
+ inputStream.forget(), 1024);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return nullptr;
+ }
+ inputStream = std::move(bufStream);
+ }
+
+ // Figure out how much data we've been passed.
+ uint64_t length;
+ rv = inputStream->Available(&length);
+ if (NS_FAILED(rv) || length > UINT32_MAX) {
+ return nullptr;
+ }
+
+ // Write the data into a SourceBuffer.
+ RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer();
+ sourceBuffer->ExpectLength(length);
+ rv = sourceBuffer->AppendFromInputStream(inputStream, length);
+ if (NS_FAILED(rv)) {
+ return nullptr;
+ }
+ // Make sure our sourceBuffer is marked as complete.
+ if (sourceBuffer->IsComplete()) {
+ NS_WARNING(
+ "The SourceBuffer was unexpectedly marked as complete. This may "
+ "indicate either an OOM condition, or that imagelib was not "
+ "initialized properly.");
+ return nullptr;
+ }
+ sourceBuffer->Complete(NS_OK);
+
+ RefPtr<ImageBuffer> imageBuffer = new ImageBufferImpl(sourceBuffer.forget());
+ return imageBuffer.forget();
+}
+
+/* static */
+nsresult ImageOps::DecodeMetadata(already_AddRefed<nsIInputStream> aInputStream,
+ const nsACString& aMimeType,
+ ImageMetadata& aMetadata) {
+ nsCOMPtr<nsIInputStream> inputStream = std::move(aInputStream);
+ RefPtr<ImageBuffer> buffer = CreateImageBuffer(inputStream.forget());
+ return DecodeMetadata(buffer, aMimeType, aMetadata);
+}
+
+/* static */
+nsresult ImageOps::DecodeMetadata(ImageBuffer* aBuffer,
+ const nsACString& aMimeType,
+ ImageMetadata& aMetadata) {
+ if (!aBuffer) {
+ return NS_ERROR_FAILURE;
+ }
+
+ RefPtr<SourceBuffer> sourceBuffer = aBuffer->GetSourceBuffer();
+ if (NS_WARN_IF(!sourceBuffer)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Create a decoder.
+ DecoderType decoderType =
+ DecoderFactory::GetDecoderType(PromiseFlatCString(aMimeType).get());
+ RefPtr<Decoder> decoder = DecoderFactory::CreateAnonymousMetadataDecoder(
+ decoderType, WrapNotNull(sourceBuffer));
+ if (!decoder) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Run the decoder synchronously.
+ RefPtr<IDecodingTask> task =
+ new AnonymousDecodingTask(WrapNotNull(decoder), /* aResumable */ false);
+ task->Run();
+ if (!decoder->GetDecodeDone() || decoder->HasError()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ aMetadata = decoder->GetImageMetadata();
+ if (aMetadata.GetNativeSizes().IsEmpty() && aMetadata.HasSize()) {
+ aMetadata.AddNativeSize(aMetadata.GetSize());
+ }
+
+ return NS_OK;
+}
+
+/* static */ already_AddRefed<gfx::SourceSurface> ImageOps::DecodeToSurface(
+ already_AddRefed<nsIInputStream> aInputStream, const nsACString& aMimeType,
+ uint32_t aFlags, const Maybe<IntSize>& aSize /* = Nothing() */) {
+ nsCOMPtr<nsIInputStream> inputStream = std::move(aInputStream);
+ RefPtr<ImageBuffer> buffer = CreateImageBuffer(inputStream.forget());
+ return DecodeToSurface(buffer, aMimeType, aFlags, aSize);
+}
+
+/* static */ already_AddRefed<gfx::SourceSurface> ImageOps::DecodeToSurface(
+ ImageBuffer* aBuffer, const nsACString& aMimeType, uint32_t aFlags,
+ const Maybe<IntSize>& aSize /* = Nothing() */) {
+ if (!aBuffer) {
+ return nullptr;
+ }
+
+ RefPtr<SourceBuffer> sourceBuffer = aBuffer->GetSourceBuffer();
+ if (NS_WARN_IF(!sourceBuffer)) {
+ return nullptr;
+ }
+
+ // Create a decoder.
+ DecoderType decoderType =
+ DecoderFactory::GetDecoderType(PromiseFlatCString(aMimeType).get());
+ RefPtr<Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(
+ decoderType, WrapNotNull(sourceBuffer), aSize,
+ DecoderFlags::FIRST_FRAME_ONLY, ToSurfaceFlags(aFlags));
+ if (!decoder) {
+ return nullptr;
+ }
+
+ // Run the decoder synchronously.
+ RefPtr<IDecodingTask> task =
+ new AnonymousDecodingTask(WrapNotNull(decoder), /* aResumable */ false);
+ task->Run();
+ if (!decoder->GetDecodeDone() || decoder->HasError()) {
+ return nullptr;
+ }
+
+ // Pull out the surface.
+ RawAccessFrameRef frame = decoder->GetCurrentFrameRef();
+ if (!frame) {
+ return nullptr;
+ }
+
+ RefPtr<SourceSurface> surface = frame->GetSourceSurface();
+ if (!surface) {
+ return nullptr;
+ }
+
+ return surface.forget();
+}
+
+} // namespace mozilla::image
diff --git a/image/ImageOps.h b/image/ImageOps.h
new file mode 100644
index 0000000000..3a97ad00ba
--- /dev/null
+++ b/image/ImageOps.h
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_ImageOps_h
+#define mozilla_image_ImageOps_h
+
+#include "nsCOMPtr.h"
+#include "nsRect.h"
+#include "ImageMetadata.h"
+
+class gfxDrawable;
+class imgIContainer;
+class nsIInputStream;
+
+namespace mozilla {
+
+namespace gfx {
+class SourceSurface;
+}
+
+namespace image {
+
+class Image;
+struct Orientation;
+class SourceBuffer;
+
+class ImageOps {
+ public:
+ class ImageBuffer {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageOps::ImageBuffer);
+
+ protected:
+ friend class ImageOps;
+
+ ImageBuffer() = default;
+ virtual ~ImageBuffer() = default;
+
+ virtual already_AddRefed<SourceBuffer> GetSourceBuffer() const = 0;
+ };
+
+ /**
+ * Creates a version of an existing image which does not animate and is frozen
+ * at the first frame.
+ *
+ * @param aImage The existing image.
+ */
+ static already_AddRefed<Image> Freeze(Image* aImage);
+ static already_AddRefed<imgIContainer> Freeze(imgIContainer* aImage);
+
+ /**
+ * Creates a clipped version of an existing image. Animation is unaffected.
+ *
+ * @param aImage The existing image.
+ * @param aClip The rectangle to clip the image against.
+ * @param aSVGViewportSize The specific viewort size of aImage. Unless aImage
+ * is a vector image without intrinsic size, this
+ * argument should be pass as Nothing().
+ */
+ static already_AddRefed<Image> Clip(
+ Image* aImage, nsIntRect aClip,
+ const Maybe<nsSize>& aSVGViewportSize = Nothing());
+ static already_AddRefed<imgIContainer> Clip(
+ imgIContainer* aImage, nsIntRect aClip,
+ const Maybe<nsSize>& aSVGViewportSize = Nothing());
+
+ /**
+ * Creates a version of an existing image which is rotated and/or flipped to
+ * the specified orientation.
+ *
+ * @param aImage The existing image.
+ * @param aOrientation The desired orientation.
+ */
+ static already_AddRefed<Image> Orient(Image* aImage,
+ Orientation aOrientation);
+ static already_AddRefed<imgIContainer> Orient(imgIContainer* aImage,
+ Orientation aOrientation);
+
+ /**
+ * Creates a version of an existing image which undoes any rotation and/or
+ * flipping that it has automatically handled.
+ *
+ * This only undoes the effect of a RasterImage's automatic orientation
+ * handling.
+ */
+ static already_AddRefed<imgIContainer> Unorient(imgIContainer* aImage);
+
+ /**
+ * Creates an image from a gfxDrawable.
+ *
+ * @param aDrawable The gfxDrawable.
+ */
+ static already_AddRefed<imgIContainer> CreateFromDrawable(
+ gfxDrawable* aDrawable);
+
+ /**
+ * Create a buffer to be used with DecodeMetadata and DecodeToSurface. Reusing
+ * an ImageBuffer representing the given input stream is more efficient if one
+ * has multiple Decode* calls to make on that stream.
+ *
+ * @param aInputStream An input stream containing an encoded image. The
+ * ownership is taken.
+ * @return An image buffer derived from the input stream.
+ */
+ static already_AddRefed<ImageBuffer> CreateImageBuffer(
+ already_AddRefed<nsIInputStream> aInputStream);
+
+ /**
+ * Decodes an image's metadata from an nsIInputStream into the given
+ * structure. This function may be called off-main-thread.
+ *
+ * @param aInputStream An input stream containing an encoded image. Ownership
+ * is taken.
+ * @param aMimeType The MIME type of the image.
+ * @param aMetadata Where the image metadata is stored upon success.
+ * @return The status of the operation.
+ */
+ static nsresult DecodeMetadata(already_AddRefed<nsIInputStream> aInputStream,
+ const nsACString& aMimeType,
+ ImageMetadata& aMetadata);
+
+ /**
+ * Same as above but takes an ImageBuffer instead of nsIInputStream.
+ */
+ static nsresult DecodeMetadata(ImageBuffer* aBuffer,
+ const nsACString& aMimeType,
+ ImageMetadata& aMetadata);
+
+ /**
+ * Decodes an image from an nsIInputStream directly into a SourceSurface,
+ * without ever creating an Image or imgIContainer (which are mostly
+ * main-thread-only). That means that this function may be called
+ * off-main-thread.
+ *
+ * @param aInputStream An input stream containing an encoded image. The
+ * ownership is taken.
+ * @param aMimeType The MIME type of the image.
+ * @param aFlags Flags of the imgIContainer::FLAG_DECODE_* variety.
+ * @return A SourceSurface containing the first frame of the image at its
+ * intrinsic size, or nullptr if the image cannot be decoded.
+ */
+ static already_AddRefed<gfx::SourceSurface> DecodeToSurface(
+ already_AddRefed<nsIInputStream> aInputStream,
+ const nsACString& aMimeType, uint32_t aFlags,
+ const Maybe<gfx::IntSize>& aSize = Nothing());
+
+ /**
+ * Same as above but takes an ImageBuffer instead of nsIInputStream.
+ */
+ static already_AddRefed<gfx::SourceSurface> DecodeToSurface(
+ ImageBuffer* aBuffer, const nsACString& aMimeType, uint32_t aFlags,
+ const Maybe<gfx::IntSize>& aSize = Nothing());
+
+ private:
+ class ImageBufferImpl;
+
+ // This is a static utility class, so disallow instantiation.
+ virtual ~ImageOps() = 0;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_ImageOps_h
diff --git a/image/ImageRegion.h b/image/ImageRegion.h
new file mode 100644
index 0000000000..ed592bbbea
--- /dev/null
+++ b/image/ImageRegion.h
@@ -0,0 +1,273 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_ImageRegion_h
+#define mozilla_image_ImageRegion_h
+
+#include "gfxMatrix.h"
+#include "gfxPoint.h"
+#include "gfxRect.h"
+#include "gfxTypes.h"
+#include "mozilla/gfx/Matrix.h"
+#include "mozilla/gfx/Types.h"
+#include "nsSize.h"
+#include "PLDHashTable.h" // for PLDHashNumber
+
+namespace mozilla {
+namespace image {
+
+/**
+ * An axis-aligned rectangle in tiled image space, with an optional sampling
+ * restriction rect. The drawing code ensures that if a sampling restriction
+ * rect is present, any pixels sampled during the drawing process are found
+ * within that rect.
+ *
+ * The sampling restriction rect exists primarily for callers which perform
+ * pixel snapping. Other callers should generally use one of the Create()
+ * overloads.
+ */
+class ImageRegion {
+ typedef mozilla::gfx::ExtendMode ExtendMode;
+
+ public:
+ static ImageRegion Empty() {
+ return ImageRegion(gfxRect(), ExtendMode::CLAMP);
+ }
+
+ static ImageRegion Create(const gfxRect& aRect,
+ ExtendMode aExtendMode = ExtendMode::CLAMP) {
+ return ImageRegion(aRect, aExtendMode);
+ }
+
+ static ImageRegion Create(const gfxSize& aSize,
+ ExtendMode aExtendMode = ExtendMode::CLAMP) {
+ return ImageRegion(gfxRect(0, 0, aSize.width, aSize.height), aExtendMode);
+ }
+
+ static ImageRegion Create(const nsIntSize& aSize,
+ ExtendMode aExtendMode = ExtendMode::CLAMP) {
+ return ImageRegion(gfxRect(0, 0, aSize.width, aSize.height), aExtendMode);
+ }
+
+ static ImageRegion CreateWithSamplingRestriction(
+ const gfxRect& aRect, const gfxRect& aRestriction,
+ ExtendMode aExtendMode = ExtendMode::CLAMP) {
+ return ImageRegion(aRect, aRestriction, aExtendMode);
+ }
+
+ bool IsRestricted() const { return mIsRestricted; }
+ const gfxRect& Rect() const { return mRect; }
+
+ const gfxRect& Restriction() const {
+ MOZ_ASSERT(mIsRestricted);
+ return mRestriction;
+ }
+
+ bool RestrictionContains(const gfxRect& aRect) const {
+ if (!mIsRestricted) {
+ return true;
+ }
+ return mRestriction.Contains(aRect);
+ }
+
+ ImageRegion Intersect(const gfxRect& aRect) const {
+ if (mIsRestricted) {
+ return CreateWithSamplingRestriction(aRect.Intersect(mRect),
+ aRect.Intersect(mRestriction));
+ }
+ return Create(aRect.Intersect(mRect));
+ }
+
+ gfxRect IntersectAndRestrict(const gfxRect& aRect) const {
+ gfxRect intersection = mRect.Intersect(aRect);
+ if (mIsRestricted) {
+ intersection = mRestriction.Intersect(intersection);
+ }
+ return intersection;
+ }
+
+ void MoveBy(gfxFloat dx, gfxFloat dy) {
+ mRect.MoveBy(dx, dy);
+ if (mIsRestricted) {
+ mRestriction.MoveBy(dx, dy);
+ }
+ }
+
+ void Scale(gfxFloat sx, gfxFloat sy) {
+ mRect.Scale(sx, sy);
+ if (mIsRestricted) {
+ mRestriction.Scale(sx, sy);
+ }
+ }
+
+ void TransformBy(const gfxMatrix& aMatrix) {
+ mRect = aMatrix.TransformRect(mRect);
+ if (mIsRestricted) {
+ mRestriction = aMatrix.TransformRect(mRestriction);
+ }
+ }
+
+ void TransformBoundsBy(const gfxMatrix& aMatrix) {
+ mRect = aMatrix.TransformBounds(mRect);
+ if (mIsRestricted) {
+ mRestriction = aMatrix.TransformBounds(mRestriction);
+ }
+ }
+
+ ImageRegion operator-(const gfxPoint& aPt) const {
+ if (mIsRestricted) {
+ return CreateWithSamplingRestriction(mRect - aPt, mRestriction - aPt);
+ }
+ return Create(mRect - aPt);
+ }
+
+ ImageRegion operator+(const gfxPoint& aPt) const {
+ if (mIsRestricted) {
+ return CreateWithSamplingRestriction(mRect + aPt, mRestriction + aPt);
+ }
+ return Create(mRect + aPt);
+ }
+
+ gfx::ExtendMode GetExtendMode() const { return mExtendMode; }
+
+ /* ImageRegion() : mIsRestricted(false) { } */
+
+ private:
+ explicit ImageRegion(const gfxRect& aRect, ExtendMode aExtendMode)
+ : mRect(aRect), mExtendMode(aExtendMode), mIsRestricted(false) {}
+
+ ImageRegion(const gfxRect& aRect, const gfxRect& aRestriction,
+ ExtendMode aExtendMode)
+ : mRect(aRect),
+ mRestriction(aRestriction),
+ mExtendMode(aExtendMode),
+ mIsRestricted(true) {}
+
+ gfxRect mRect;
+ gfxRect mRestriction;
+ ExtendMode mExtendMode;
+ bool mIsRestricted;
+};
+
+/**
+ * An axis-aligned rectangle in tiled image space, with an optional sampling
+ * restriction rect. The drawing code ensures that if a sampling restriction
+ * rect is present, any pixels sampled during the drawing process are found
+ * within that rect.
+ *
+ * The sampling restriction rect exists primarily for callers which perform
+ * pixel snapping. Other callers should generally use one of the Create()
+ * overloads.
+ */
+class ImageIntRegion {
+ typedef mozilla::gfx::ExtendMode ExtendMode;
+
+ public:
+ static ImageIntRegion Empty() {
+ return ImageIntRegion(mozilla::gfx::IntRect(), ExtendMode::CLAMP);
+ }
+
+ static ImageIntRegion Create(const mozilla::gfx::IntRect& aRect,
+ ExtendMode aExtendMode = ExtendMode::CLAMP) {
+ return ImageIntRegion(aRect, aExtendMode);
+ }
+
+ static ImageIntRegion Create(const mozilla::gfx::IntSize& aSize,
+ ExtendMode aExtendMode = ExtendMode::CLAMP) {
+ return ImageIntRegion(
+ mozilla::gfx::IntRect(0, 0, aSize.width, aSize.height), aExtendMode);
+ }
+
+ static ImageIntRegion CreateWithSamplingRestriction(
+ const mozilla::gfx::IntRect& aRect,
+ const mozilla::gfx::IntRect& aRestriction,
+ ExtendMode aExtendMode = ExtendMode::CLAMP) {
+ return ImageIntRegion(aRect, aRestriction, aExtendMode);
+ }
+
+ bool IsRestricted() const { return mIsRestricted; }
+ const mozilla::gfx::IntRect& Rect() const { return mRect; }
+
+ const mozilla::gfx::IntRect& Restriction() const {
+ MOZ_ASSERT(mIsRestricted);
+ return mRestriction;
+ }
+
+ bool RestrictionContains(const mozilla::gfx::IntRect& aRect) const {
+ if (!mIsRestricted) {
+ return true;
+ }
+ return mRestriction.Contains(aRect);
+ }
+
+ ImageIntRegion Intersect(const mozilla::gfx::IntRect& aRect) const {
+ if (mIsRestricted) {
+ return CreateWithSamplingRestriction(aRect.Intersect(mRect),
+ aRect.Intersect(mRestriction));
+ }
+ return Create(aRect.Intersect(mRect));
+ }
+
+ mozilla::gfx::IntRect IntersectAndRestrict(
+ const mozilla::gfx::IntRect& aRect) const {
+ mozilla::gfx::IntRect intersection = mRect.Intersect(aRect);
+ if (mIsRestricted) {
+ intersection = mRestriction.Intersect(intersection);
+ }
+ return intersection;
+ }
+
+ gfx::ExtendMode GetExtendMode() const { return mExtendMode; }
+
+ ImageRegion ToImageRegion() const {
+ if (mIsRestricted) {
+ return ImageRegion::CreateWithSamplingRestriction(
+ gfxRect(mRect.x, mRect.y, mRect.width, mRect.height),
+ gfxRect(mRestriction.x, mRestriction.y, mRestriction.width,
+ mRestriction.height),
+ mExtendMode);
+ }
+ return ImageRegion::Create(
+ gfxRect(mRect.x, mRect.y, mRect.width, mRect.height), mExtendMode);
+ }
+
+ bool operator==(const ImageIntRegion& aOther) const {
+ return mExtendMode == aOther.mExtendMode &&
+ mIsRestricted == aOther.mIsRestricted &&
+ mRect.IsEqualEdges(aOther.mRect) &&
+ (!mIsRestricted || mRestriction.IsEqualEdges(aOther.mRestriction));
+ }
+
+ PLDHashNumber Hash() const {
+ return HashGeneric(mRect.x, mRect.y, mRect.width, mRect.height,
+ mRestriction.x, mRestriction.y, mRestriction.width,
+ mRestriction.height, mExtendMode, mIsRestricted);
+ }
+
+ /* ImageIntRegion() : mIsRestricted(false) { } */
+
+ private:
+ explicit ImageIntRegion(const mozilla::gfx::IntRect& aRect,
+ ExtendMode aExtendMode)
+ : mRect(aRect), mExtendMode(aExtendMode), mIsRestricted(false) {}
+
+ ImageIntRegion(const mozilla::gfx::IntRect& aRect,
+ const mozilla::gfx::IntRect& aRestriction,
+ ExtendMode aExtendMode)
+ : mRect(aRect),
+ mRestriction(aRestriction),
+ mExtendMode(aExtendMode),
+ mIsRestricted(true) {}
+
+ mozilla::gfx::IntRect mRect;
+ mozilla::gfx::IntRect mRestriction;
+ ExtendMode mExtendMode;
+ bool mIsRestricted;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_ImageRegion_h
diff --git a/image/ImageWrapper.cpp b/image/ImageWrapper.cpp
new file mode 100644
index 0000000000..eafd6ffe04
--- /dev/null
+++ b/image/ImageWrapper.cpp
@@ -0,0 +1,289 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageWrapper.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
+#include "Orientation.h"
+#include "mozilla/image/Resolution.h"
+
+#include "mozilla/MemoryReporting.h"
+
+namespace mozilla {
+
+using dom::Document;
+using gfx::IntSize;
+using gfx::SamplingFilter;
+using gfx::SourceSurface;
+using layers::ImageContainer;
+
+namespace image {
+
+// Inherited methods from Image.
+
+already_AddRefed<ProgressTracker> ImageWrapper::GetProgressTracker() {
+ return mInnerImage->GetProgressTracker();
+}
+
+size_t ImageWrapper::SizeOfSourceWithComputedFallback(
+ SizeOfState& aState) const {
+ return mInnerImage->SizeOfSourceWithComputedFallback(aState);
+}
+
+void ImageWrapper::CollectSizeOfSurfaces(
+ nsTArray<SurfaceMemoryCounter>& aCounters,
+ MallocSizeOf aMallocSizeOf) const {
+ mInnerImage->CollectSizeOfSurfaces(aCounters, aMallocSizeOf);
+}
+
+void ImageWrapper::IncrementAnimationConsumers() {
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Main thread only to encourage serialization "
+ "with DecrementAnimationConsumers");
+ mInnerImage->IncrementAnimationConsumers();
+}
+
+void ImageWrapper::DecrementAnimationConsumers() {
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Main thread only to encourage serialization "
+ "with IncrementAnimationConsumers");
+ mInnerImage->DecrementAnimationConsumers();
+}
+
+#ifdef DEBUG
+uint32_t ImageWrapper::GetAnimationConsumers() {
+ return mInnerImage->GetAnimationConsumers();
+}
+#endif
+
+nsresult ImageWrapper::OnImageDataAvailable(nsIRequest* aRequest,
+ nsIInputStream* aInStr,
+ uint64_t aSourceOffset,
+ uint32_t aCount) {
+ return mInnerImage->OnImageDataAvailable(aRequest, aInStr, aSourceOffset,
+ aCount);
+}
+
+nsresult ImageWrapper::OnImageDataComplete(nsIRequest* aRequest,
+ nsresult aStatus, bool aLastPart) {
+ return mInnerImage->OnImageDataComplete(aRequest, aStatus, aLastPart);
+}
+
+void ImageWrapper::OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) {
+ return mInnerImage->OnSurfaceDiscarded(aSurfaceKey);
+}
+
+void ImageWrapper::SetInnerWindowID(uint64_t aInnerWindowId) {
+ mInnerImage->SetInnerWindowID(aInnerWindowId);
+}
+
+uint64_t ImageWrapper::InnerWindowID() const {
+ return mInnerImage->InnerWindowID();
+}
+
+bool ImageWrapper::HasError() { return mInnerImage->HasError(); }
+
+void ImageWrapper::SetHasError() { mInnerImage->SetHasError(); }
+
+nsIURI* ImageWrapper::GetURI() const { return mInnerImage->GetURI(); }
+
+// Methods inherited from XPCOM interfaces.
+
+NS_IMPL_ISUPPORTS(ImageWrapper, imgIContainer)
+
+NS_IMETHODIMP
+ImageWrapper::GetWidth(int32_t* aWidth) {
+ return mInnerImage->GetWidth(aWidth);
+}
+
+NS_IMETHODIMP
+ImageWrapper::GetHeight(int32_t* aHeight) {
+ return mInnerImage->GetHeight(aHeight);
+}
+
+void ImageWrapper::MediaFeatureValuesChangedAllDocuments(
+ const mozilla::MediaFeatureChange& aChange) {}
+
+nsresult ImageWrapper::GetNativeSizes(nsTArray<IntSize>& aNativeSizes) {
+ return mInnerImage->GetNativeSizes(aNativeSizes);
+}
+
+size_t ImageWrapper::GetNativeSizesLength() {
+ return mInnerImage->GetNativeSizesLength();
+}
+
+NS_IMETHODIMP
+ImageWrapper::GetIntrinsicSize(nsSize* aSize) {
+ return mInnerImage->GetIntrinsicSize(aSize);
+}
+
+Maybe<AspectRatio> ImageWrapper::GetIntrinsicRatio() {
+ return mInnerImage->GetIntrinsicRatio();
+}
+
+nsresult ImageWrapper::GetHotspotX(int32_t* aX) {
+ return Image::GetHotspotX(aX);
+}
+
+nsresult ImageWrapper::GetHotspotY(int32_t* aY) {
+ return Image::GetHotspotY(aY);
+}
+
+NS_IMETHODIMP_(Orientation)
+ImageWrapper::GetOrientation() { return mInnerImage->GetOrientation(); }
+
+NS_IMETHODIMP_(Resolution)
+ImageWrapper::GetResolution() { return mInnerImage->GetResolution(); }
+
+NS_IMETHODIMP
+ImageWrapper::GetType(uint16_t* aType) { return mInnerImage->GetType(aType); }
+
+NS_IMETHODIMP
+ImageWrapper::GetProviderId(uint32_t* aId) {
+ return mInnerImage->GetProviderId(aId);
+}
+
+NS_IMETHODIMP
+ImageWrapper::GetAnimated(bool* aAnimated) {
+ return mInnerImage->GetAnimated(aAnimated);
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+ImageWrapper::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) {
+ return mInnerImage->GetFrame(aWhichFrame, aFlags);
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+ImageWrapper::GetFrameAtSize(const IntSize& aSize, uint32_t aWhichFrame,
+ uint32_t aFlags) {
+ return mInnerImage->GetFrameAtSize(aSize, aWhichFrame, aFlags);
+}
+
+NS_IMETHODIMP_(bool)
+ImageWrapper::WillDrawOpaqueNow() { return mInnerImage->WillDrawOpaqueNow(); }
+
+NS_IMETHODIMP_(bool)
+ImageWrapper::IsImageContainerAvailable(WindowRenderer* aRenderer,
+ uint32_t aFlags) {
+ return mInnerImage->IsImageContainerAvailable(aRenderer, aFlags);
+}
+
+NS_IMETHODIMP_(ImgDrawResult)
+ImageWrapper::GetImageProvider(WindowRenderer* aRenderer,
+ const gfx::IntSize& aSize,
+ const SVGImageContext& aSVGContext,
+ const Maybe<ImageIntRegion>& aRegion,
+ uint32_t aFlags,
+ WebRenderImageProvider** aProvider) {
+ return mInnerImage->GetImageProvider(aRenderer, aSize, aSVGContext, aRegion,
+ aFlags, aProvider);
+}
+
+NS_IMETHODIMP_(ImgDrawResult)
+ImageWrapper::Draw(gfxContext* aContext, const nsIntSize& aSize,
+ const ImageRegion& aRegion, uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ const SVGImageContext& aSVGContext, uint32_t aFlags,
+ float aOpacity) {
+ return mInnerImage->Draw(aContext, aSize, aRegion, aWhichFrame,
+ aSamplingFilter, aSVGContext, aFlags, aOpacity);
+}
+
+NS_IMETHODIMP
+ImageWrapper::StartDecoding(uint32_t aFlags, uint32_t aWhichFrame) {
+ return mInnerImage->StartDecoding(aFlags, aWhichFrame);
+}
+
+bool ImageWrapper::StartDecodingWithResult(uint32_t aFlags,
+ uint32_t aWhichFrame) {
+ return mInnerImage->StartDecodingWithResult(aFlags, aWhichFrame);
+}
+
+bool ImageWrapper::HasDecodedPixels() {
+ return InnerImage()->HasDecodedPixels();
+}
+
+imgIContainer::DecodeResult ImageWrapper::RequestDecodeWithResult(
+ uint32_t aFlags, uint32_t aWhichFrame) {
+ return mInnerImage->RequestDecodeWithResult(aFlags, aWhichFrame);
+}
+
+NS_IMETHODIMP
+ImageWrapper::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags,
+ uint32_t aWhichFrame) {
+ return mInnerImage->RequestDecodeForSize(aSize, aFlags, aWhichFrame);
+}
+
+NS_IMETHODIMP
+ImageWrapper::LockImage() {
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Main thread to encourage serialization with UnlockImage");
+ return mInnerImage->LockImage();
+}
+
+NS_IMETHODIMP
+ImageWrapper::UnlockImage() {
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Main thread to encourage serialization with LockImage");
+ return mInnerImage->UnlockImage();
+}
+
+NS_IMETHODIMP
+ImageWrapper::RequestDiscard() { return mInnerImage->RequestDiscard(); }
+
+NS_IMETHODIMP_(void)
+ImageWrapper::RequestRefresh(const TimeStamp& aTime) {
+ return mInnerImage->RequestRefresh(aTime);
+}
+
+NS_IMETHODIMP
+ImageWrapper::GetAnimationMode(uint16_t* aAnimationMode) {
+ return mInnerImage->GetAnimationMode(aAnimationMode);
+}
+
+NS_IMETHODIMP
+ImageWrapper::SetAnimationMode(uint16_t aAnimationMode) {
+ return mInnerImage->SetAnimationMode(aAnimationMode);
+}
+
+NS_IMETHODIMP
+ImageWrapper::ResetAnimation() { return mInnerImage->ResetAnimation(); }
+
+NS_IMETHODIMP_(float)
+ImageWrapper::GetFrameIndex(uint32_t aWhichFrame) {
+ return mInnerImage->GetFrameIndex(aWhichFrame);
+}
+
+NS_IMETHODIMP_(int32_t)
+ImageWrapper::GetFirstFrameDelay() { return mInnerImage->GetFirstFrameDelay(); }
+
+NS_IMETHODIMP_(void)
+ImageWrapper::SetAnimationStartTime(const TimeStamp& aTime) {
+ mInnerImage->SetAnimationStartTime(aTime);
+}
+
+void ImageWrapper::PropagateUseCounters(Document* aReferencingDocument) {
+ mInnerImage->PropagateUseCounters(aReferencingDocument);
+}
+
+nsIntSize ImageWrapper::OptimalImageSizeForDest(const gfxSize& aDest,
+ uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ uint32_t aFlags) {
+ return mInnerImage->OptimalImageSizeForDest(aDest, aWhichFrame,
+ aSamplingFilter, aFlags);
+}
+
+NS_IMETHODIMP_(nsIntRect)
+ImageWrapper::GetImageSpaceInvalidationRect(const nsIntRect& aRect) {
+ return mInnerImage->GetImageSpaceInvalidationRect(aRect);
+}
+
+already_AddRefed<imgIContainer> ImageWrapper::Unwrap() {
+ return mInnerImage->Unwrap();
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/ImageWrapper.h b/image/ImageWrapper.h
new file mode 100644
index 0000000000..d72393e976
--- /dev/null
+++ b/image/ImageWrapper.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_ImageWrapper_h
+#define mozilla_image_ImageWrapper_h
+
+#include "mozilla/MemoryReporting.h"
+#include "Image.h"
+
+namespace mozilla {
+namespace image {
+
+/**
+ * Abstract superclass for Images that wrap other Images.
+ */
+class ImageWrapper : public Image {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_IMGICONTAINER
+
+ // Inherited methods from Image.
+ virtual already_AddRefed<ProgressTracker> GetProgressTracker() override;
+
+ virtual size_t SizeOfSourceWithComputedFallback(
+ SizeOfState& aState) const override;
+ virtual void CollectSizeOfSurfaces(nsTArray<SurfaceMemoryCounter>& aCounters,
+ MallocSizeOf aMallocSizeOf) const override;
+
+ virtual void IncrementAnimationConsumers() override;
+ virtual void DecrementAnimationConsumers() override;
+#ifdef DEBUG
+ virtual uint32_t GetAnimationConsumers() override;
+#endif
+
+ virtual nsresult OnImageDataAvailable(nsIRequest* aRequest,
+ nsIInputStream* aInStr,
+ uint64_t aSourceOffset,
+ uint32_t aCount) override;
+ virtual nsresult OnImageDataComplete(nsIRequest* aRequest, nsresult aStatus,
+ bool aLastPart) override;
+
+ virtual void OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) override;
+
+ virtual void SetInnerWindowID(uint64_t aInnerWindowId) override;
+ virtual uint64_t InnerWindowID() const override;
+
+ virtual bool HasError() override;
+ virtual void SetHasError() override;
+
+ nsIURI* GetURI() const override;
+
+ protected:
+ explicit ImageWrapper(Image* aInnerImage) : mInnerImage(aInnerImage) {
+ MOZ_ASSERT(aInnerImage, "Need an image to wrap");
+ }
+
+ virtual ~ImageWrapper() {}
+
+ /**
+ * Returns a weak reference to the inner image wrapped by this ImageWrapper.
+ */
+ Image* InnerImage() const { return mInnerImage.get(); }
+
+ void SetInnerImage(Image* aInnerImage) {
+ MOZ_ASSERT(aInnerImage, "Need an image to wrap");
+ mInnerImage = aInnerImage;
+ }
+
+ private:
+ RefPtr<Image> mInnerImage;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_ImageWrapper_h
diff --git a/image/ImgDrawResult.h b/image/ImgDrawResult.h
new file mode 100644
index 0000000000..d33b63d71c
--- /dev/null
+++ b/image/ImgDrawResult.h
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_ImgDrawResult_h
+#define mozilla_image_ImgDrawResult_h
+
+#include <cstdint> // for uint8_t
+#include "mozilla/Attributes.h"
+#include "mozilla/Likely.h"
+
+namespace mozilla {
+namespace image {
+
+/**
+ * An enumeration representing the result of a drawing operation.
+ *
+ * Most users of ImgDrawResult will only be interested in whether the value is
+ * SUCCESS or not. The other values are primarily useful for debugging and error
+ * handling.
+ *
+ * SUCCESS: We successfully drew a completely decoded frame of the requested
+ * size. Drawing again with FLAG_SYNC_DECODE would not change the result.
+ *
+ * SUCCESS_NOT_COMPLETE: The image was drawn successfully and completely, but
+ * it hasn't notified about the sync-decode yet. This can only happen when
+ * layout pokes at the internal image state beforehand via the result of
+ * StartDecodingWithResult. This should probably go away eventually, somehow,
+ * see bug 1471583.
+ *
+ * INCOMPLETE: We successfully drew a frame that was partially decoded. (Note
+ * that successfully drawing a partially decoded frame may not actually draw any
+ * pixels!) Drawing again with FLAG_SYNC_DECODE would improve the result.
+ *
+ * WRONG_SIZE: We successfully drew a wrongly-sized frame that had to be scaled.
+ * This is only returned if drawing again with FLAG_SYNC_DECODE would improve
+ * the result; if the size requested was larger than the intrinsic size of the
+ * image, for example, we would generally have to scale whether FLAG_SYNC_DECODE
+ * was specified or not, and therefore we would not return WRONG_SIZE.
+ *
+ * NOT_READY: We failed to draw because no decoded version of the image was
+ * available. Drawing again with FLAG_SYNC_DECODE would improve the result.
+ * (Though FLAG_SYNC_DECODE will not necessarily work until after the image's
+ * load event!)
+ *
+ * TEMPORARY_ERROR: We failed to draw due to a temporary error. Drawing may
+ * succeed at a later time.
+ *
+ * BAD_IMAGE: We failed to draw because the image has an error. This is a
+ * permanent condition.
+ *
+ * BAD_ARGS: We failed to draw because bad arguments were passed to draw().
+ *
+ * NOT_SUPPORTED: The requested operation is not supported, but the image is
+ * otherwise valid.
+ */
+enum class [[nodiscard]] ImgDrawResult : uint8_t {
+ SUCCESS,
+ SUCCESS_NOT_COMPLETE,
+ INCOMPLETE,
+ WRONG_SIZE,
+ NOT_READY,
+ TEMPORARY_ERROR,
+ BAD_IMAGE,
+ BAD_ARGS,
+ NOT_SUPPORTED
+};
+
+/**
+ * You can combine ImgDrawResults with &. By analogy to bitwise-&, the result is
+ * ImgDrawResult::SUCCESS only if both operands are ImgDrawResult::SUCCESS.
+ * Otherwise, a failing ImgDrawResult is returned; we favor the left operand's
+ * failure when deciding which failure to return, with the exception that we
+ * always prefer any other kind of failure over ImgDrawResult::BAD_IMAGE, since
+ * other failures are recoverable and we want to know if any recoverable
+ * failures occurred.
+ */
+inline ImgDrawResult operator&(const ImgDrawResult aLeft,
+ const ImgDrawResult aRight) {
+ if (MOZ_LIKELY(aLeft == ImgDrawResult::SUCCESS)) {
+ return aRight;
+ }
+
+ if (aLeft == ImgDrawResult::NOT_SUPPORTED ||
+ aRight == ImgDrawResult::NOT_SUPPORTED) {
+ return ImgDrawResult::NOT_SUPPORTED;
+ }
+
+ if ((aLeft == ImgDrawResult::BAD_IMAGE ||
+ aLeft == ImgDrawResult::SUCCESS_NOT_COMPLETE) &&
+ aRight != ImgDrawResult::SUCCESS &&
+ aRight != ImgDrawResult::SUCCESS_NOT_COMPLETE) {
+ return aRight;
+ }
+ return aLeft;
+}
+
+inline ImgDrawResult& operator&=(ImgDrawResult& aLeft,
+ const ImgDrawResult aRight) {
+ aLeft = aLeft & aRight;
+ return aLeft;
+}
+
+/**
+ * A struct used during painting to provide input flags to determine how
+ * imagelib draw calls should behave and an output ImgDrawResult to return
+ * information about the result of any imagelib draw calls that may have
+ * occurred.
+ */
+struct imgDrawingParams {
+ explicit imgDrawingParams(uint32_t aImageFlags = 0)
+ : imageFlags(aImageFlags), result(ImgDrawResult::SUCCESS) {}
+
+ const uint32_t imageFlags; // imgIContainer::FLAG_* image flags to pass to
+ // image lib draw calls.
+ ImgDrawResult result; // To return results from image lib painting.
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_ImgDrawResult_h
diff --git a/image/LookupResult.h b/image/LookupResult.h
new file mode 100644
index 0000000000..bbd1cca2a7
--- /dev/null
+++ b/image/LookupResult.h
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * LookupResult is the return type of SurfaceCache's Lookup*() functions. It
+ * combines a surface with relevant metadata tracked by SurfaceCache.
+ */
+
+#ifndef mozilla_image_LookupResult_h
+#define mozilla_image_LookupResult_h
+
+#include <utility>
+
+#include "ISurfaceProvider.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/gfx/Point.h" // for IntSize
+
+namespace mozilla {
+namespace image {
+
+enum class MatchType : uint8_t {
+ NOT_FOUND, // No matching surface and no placeholder.
+ PENDING, // Found a matching placeholder, but no surface.
+ EXACT, // Found a surface that matches exactly.
+ SUBSTITUTE_BECAUSE_NOT_FOUND, // No exact match, but found a similar one.
+ SUBSTITUTE_BECAUSE_PENDING, // Found a similar surface and a placeholder
+ // for an exact match.
+
+ /* No exact match, but this should be considered an exact match for purposes
+ * of deciding whether or not to request a new decode. This is because the
+ * cache has determined that callers require too many size variants of this
+ * image. It determines the set of sizes which best represent the image, and
+ * will only suggest decoding of unavailable sizes from that set. */
+ SUBSTITUTE_BECAUSE_BEST
+};
+
+/**
+ * LookupResult is the return type of SurfaceCache's Lookup*() functions. It
+ * combines a surface with relevant metadata tracked by SurfaceCache.
+ */
+class MOZ_STACK_CLASS LookupResult {
+ public:
+ explicit LookupResult(MatchType aMatchType)
+ : mMatchType(aMatchType), mFailedToRequestDecode(false) {
+ MOZ_ASSERT(
+ mMatchType == MatchType::NOT_FOUND || mMatchType == MatchType::PENDING,
+ "Only NOT_FOUND or PENDING make sense with no surface");
+ }
+
+ LookupResult(LookupResult&& aOther)
+ : mSurface(std::move(aOther.mSurface)),
+ mMatchType(aOther.mMatchType),
+ mSuggestedSize(aOther.mSuggestedSize),
+ mFailedToRequestDecode(aOther.mFailedToRequestDecode) {}
+
+ LookupResult(DrawableSurface&& aSurface, MatchType aMatchType)
+ : mSurface(std::move(aSurface)),
+ mMatchType(aMatchType),
+ mFailedToRequestDecode(false) {
+ MOZ_ASSERT(!mSurface || !(mMatchType == MatchType::NOT_FOUND ||
+ mMatchType == MatchType::PENDING),
+ "Only NOT_FOUND or PENDING make sense with no surface");
+ MOZ_ASSERT(mSurface || mMatchType == MatchType::NOT_FOUND ||
+ mMatchType == MatchType::PENDING,
+ "NOT_FOUND or PENDING do not make sense with a surface");
+ }
+
+ LookupResult(MatchType aMatchType, const gfx::IntSize& aSuggestedSize)
+ : mMatchType(aMatchType),
+ mSuggestedSize(aSuggestedSize),
+ mFailedToRequestDecode(false) {
+ MOZ_ASSERT(
+ mMatchType == MatchType::NOT_FOUND || mMatchType == MatchType::PENDING,
+ "Only NOT_FOUND or PENDING make sense with no surface");
+ }
+
+ LookupResult(DrawableSurface&& aSurface, MatchType aMatchType,
+ const gfx::IntSize& aSuggestedSize)
+ : mSurface(std::move(aSurface)),
+ mMatchType(aMatchType),
+ mSuggestedSize(aSuggestedSize),
+ mFailedToRequestDecode(false) {
+ MOZ_ASSERT(!mSurface || !(mMatchType == MatchType::NOT_FOUND ||
+ mMatchType == MatchType::PENDING),
+ "Only NOT_FOUND or PENDING make sense with no surface");
+ MOZ_ASSERT(mSurface || mMatchType == MatchType::NOT_FOUND ||
+ mMatchType == MatchType::PENDING,
+ "NOT_FOUND or PENDING do not make sense with a surface");
+ }
+
+ LookupResult& operator=(LookupResult&& aOther) {
+ MOZ_ASSERT(&aOther != this, "Self-move-assignment is not supported");
+ mSurface = std::move(aOther.mSurface);
+ mMatchType = aOther.mMatchType;
+ mSuggestedSize = aOther.mSuggestedSize;
+ mFailedToRequestDecode = aOther.mFailedToRequestDecode;
+ return *this;
+ }
+
+ DrawableSurface& Surface() { return mSurface; }
+ const DrawableSurface& Surface() const { return mSurface; }
+ const gfx::IntSize& SuggestedSize() const { return mSuggestedSize; }
+
+ /// @return true if this LookupResult contains a surface.
+ explicit operator bool() const { return bool(mSurface); }
+
+ /// @return what kind of match this is (exact, substitute, etc.)
+ MatchType Type() const { return mMatchType; }
+
+ void SetFailedToRequestDecode() { mFailedToRequestDecode = true; }
+ bool GetFailedToRequestDecode() { return mFailedToRequestDecode; }
+
+ private:
+ LookupResult(const LookupResult&) = delete;
+ LookupResult& operator=(const LookupResult& aOther) = delete;
+
+ DrawableSurface mSurface;
+ MatchType mMatchType;
+
+ /// mSuggestedSize will be the size of the returned surface if the result is
+ /// SUBSTITUTE_BECAUSE_BEST. It will be empty for EXACT, and can contain a
+ /// non-empty size possibly different from the returned surface (if any) for
+ /// all other results. If non-empty, it will always be the size the caller
+ /// should request any decodes at.
+ gfx::IntSize mSuggestedSize;
+
+ // True if we tried to start a decode but failed, likely because the image was
+ // too big to fit into the surface cache.
+ bool mFailedToRequestDecode;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_LookupResult_h
diff --git a/image/MultipartImage.cpp b/image/MultipartImage.cpp
new file mode 100644
index 0000000000..a52b87b099
--- /dev/null
+++ b/image/MultipartImage.cpp
@@ -0,0 +1,300 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "MultipartImage.h"
+
+#include "imgINotificationObserver.h"
+
+namespace mozilla {
+
+using gfx::IntSize;
+using gfx::SourceSurface;
+
+namespace image {
+
+///////////////////////////////////////////////////////////////////////////////
+// Helpers
+///////////////////////////////////////////////////////////////////////////////
+
+class NextPartObserver : public IProgressObserver {
+ public:
+ MOZ_DECLARE_REFCOUNTED_TYPENAME(NextPartObserver)
+ NS_INLINE_DECL_REFCOUNTING(NextPartObserver, override)
+
+ explicit NextPartObserver(MultipartImage* aOwner) : mOwner(aOwner) {
+ MOZ_ASSERT(mOwner);
+ }
+
+ void BeginObserving(Image* aImage) {
+ MOZ_ASSERT(aImage);
+ mImage = aImage;
+
+ RefPtr<ProgressTracker> tracker = mImage->GetProgressTracker();
+ tracker->AddObserver(this);
+ }
+
+ void BlockUntilDecodedAndFinishObserving() {
+ // Use RequestDecodeForSize() to block until our image finishes decoding.
+ // The size is ignored because we don't pass the FLAG_HIGH_QUALITY_SCALING
+ // flag.
+ mImage->RequestDecodeForSize(gfx::IntSize(0, 0),
+ imgIContainer::FLAG_SYNC_DECODE);
+
+ // RequestDecodeForSize() should've sent synchronous notifications that
+ // would have caused us to call FinishObserving() (and null out mImage)
+ // already. If for some reason it didn't, we should do so here.
+ if (mImage) {
+ FinishObserving();
+ }
+ }
+
+ virtual void Notify(int32_t aType,
+ const nsIntRect* aRect = nullptr) override {
+ if (!mImage) {
+ // We've already finished observing the last image we were given.
+ return;
+ }
+
+ if (aType == imgINotificationObserver::FRAME_COMPLETE) {
+ FinishObserving();
+ }
+ }
+
+ virtual void OnLoadComplete(bool aLastPart) override {
+ if (!mImage) {
+ // We've already finished observing the last image we were given.
+ return;
+ }
+
+ // Retrieve the image's intrinsic size.
+ int32_t width = 0;
+ int32_t height = 0;
+ mImage->GetWidth(&width);
+ mImage->GetHeight(&height);
+
+ // Request decoding at the intrinsic size.
+ mImage->RequestDecodeForSize(IntSize(width, height),
+ imgIContainer::DECODE_FLAGS_DEFAULT |
+ imgIContainer::FLAG_HIGH_QUALITY_SCALING);
+
+ // If there's already an error, we may never get a FRAME_COMPLETE
+ // notification, so go ahead and notify our owner right away.
+ RefPtr<ProgressTracker> tracker = mImage->GetProgressTracker();
+ if (tracker->GetProgress() & FLAG_HAS_ERROR) {
+ FinishObserving();
+ }
+ }
+
+ // Other notifications are ignored.
+ virtual void SetHasImage() override {}
+ virtual bool NotificationsDeferred() const override { return false; }
+ virtual void MarkPendingNotify() override {}
+ virtual void ClearPendingNotify() override {}
+
+ private:
+ virtual ~NextPartObserver() {}
+
+ void FinishObserving() {
+ MOZ_ASSERT(mImage);
+
+ RefPtr<ProgressTracker> tracker = mImage->GetProgressTracker();
+ tracker->RemoveObserver(this);
+ mImage = nullptr;
+
+ mOwner->FinishTransition();
+ }
+
+ MultipartImage* mOwner;
+ RefPtr<Image> mImage;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementation
+///////////////////////////////////////////////////////////////////////////////
+
+MultipartImage::MultipartImage(Image* aFirstPart)
+ : ImageWrapper(aFirstPart), mPendingNotify(false) {
+ mNextPartObserver = new NextPartObserver(this);
+}
+
+void MultipartImage::Init() {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(mTracker, "Should've called SetProgressTracker() by now");
+
+ // Start observing the first part.
+ RefPtr<ProgressTracker> firstPartTracker = InnerImage()->GetProgressTracker();
+ firstPartTracker->AddObserver(this);
+ InnerImage()->IncrementAnimationConsumers();
+}
+
+MultipartImage::~MultipartImage() {
+ // Ask our ProgressTracker to drop its weak reference to us.
+ mTracker->ResetImage();
+}
+
+NS_IMPL_ISUPPORTS_INHERITED0(MultipartImage, ImageWrapper)
+
+void MultipartImage::BeginTransitionToPart(Image* aNextPart) {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(aNextPart);
+
+ if (mNextPart) {
+ // Let the decoder catch up so we don't drop frames.
+ mNextPartObserver->BlockUntilDecodedAndFinishObserving();
+ MOZ_ASSERT(!mNextPart);
+ }
+
+ mNextPart = aNextPart;
+
+ // Start observing the next part; we'll complete the transition when
+ // NextPartObserver calls FinishTransition.
+ mNextPartObserver->BeginObserving(mNextPart);
+ mNextPart->IncrementAnimationConsumers();
+}
+
+static Progress FilterProgress(Progress aProgress) {
+ // Filter out onload blocking notifications, since we don't want to block
+ // onload for multipart images.
+ // Filter out errors, since we don't want errors in one part to error out
+ // the whole stream.
+ return aProgress & ~FLAG_HAS_ERROR;
+}
+
+void MultipartImage::FinishTransition() {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(mNextPart, "Should have a next part here");
+
+ RefPtr<ProgressTracker> newCurrentPartTracker =
+ mNextPart->GetProgressTracker();
+ if (newCurrentPartTracker->GetProgress() & FLAG_HAS_ERROR) {
+ // This frame has an error; drop it.
+ mNextPart = nullptr;
+
+ // We still need to notify, though.
+ mTracker->ResetForNewRequest();
+ RefPtr<ProgressTracker> currentPartTracker =
+ InnerImage()->GetProgressTracker();
+ mTracker->SyncNotifyProgress(
+ FilterProgress(currentPartTracker->GetProgress()));
+
+ return;
+ }
+
+ // Stop observing the current part.
+ {
+ RefPtr<ProgressTracker> currentPartTracker =
+ InnerImage()->GetProgressTracker();
+ currentPartTracker->RemoveObserver(this);
+ }
+
+ // Make the next part become the current part.
+ mTracker->ResetForNewRequest();
+ SetInnerImage(mNextPart);
+ mNextPart = nullptr;
+ newCurrentPartTracker->AddObserver(this);
+
+ // Finally, send all the notifications for the new current part and send a
+ // FRAME_UPDATE notification so that observers know to redraw.
+ mTracker->SyncNotifyProgress(
+ FilterProgress(newCurrentPartTracker->GetProgress()),
+ GetMaxSizedIntRect());
+}
+
+already_AddRefed<imgIContainer> MultipartImage::Unwrap() {
+ // Although we wrap another image, we don't allow callers to unwrap as. As far
+ // as external code is concerned, MultipartImage is atomic.
+ nsCOMPtr<imgIContainer> image = this;
+ return image.forget();
+}
+
+already_AddRefed<ProgressTracker> MultipartImage::GetProgressTracker() {
+ MOZ_ASSERT(mTracker);
+ RefPtr<ProgressTracker> tracker = mTracker;
+ return tracker.forget();
+}
+
+void MultipartImage::SetProgressTracker(ProgressTracker* aTracker) {
+ MOZ_ASSERT(aTracker);
+ MOZ_ASSERT(!mTracker);
+ mTracker = aTracker;
+}
+
+nsresult MultipartImage::OnImageDataAvailable(nsIRequest* aRequest,
+ nsIInputStream* aInStr,
+ uint64_t aSourceOffset,
+ uint32_t aCount) {
+ // Note that this method is special in that we forward it to the next part if
+ // one exists, and *not* the current part.
+
+ // We may trigger notifications that will free mNextPart, so keep it alive.
+ RefPtr<Image> nextPart = mNextPart;
+ if (nextPart) {
+ nextPart->OnImageDataAvailable(aRequest, aInStr, aSourceOffset, aCount);
+ } else {
+ InnerImage()->OnImageDataAvailable(aRequest, aInStr, aSourceOffset, aCount);
+ }
+
+ return NS_OK;
+}
+
+nsresult MultipartImage::OnImageDataComplete(nsIRequest* aRequest,
+ nsresult aStatus, bool aLastPart) {
+ // Note that this method is special in that we forward it to the next part if
+ // one exists, and *not* the current part.
+
+ // We may trigger notifications that will free mNextPart, so keep it alive.
+ RefPtr<Image> nextPart = mNextPart;
+ if (nextPart) {
+ nextPart->OnImageDataComplete(aRequest, aStatus, aLastPart);
+ } else {
+ InnerImage()->OnImageDataComplete(aRequest, aStatus, aLastPart);
+ }
+
+ return NS_OK;
+}
+
+void MultipartImage::Notify(int32_t aType,
+ const nsIntRect* aRect /* = nullptr*/) {
+ if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
+ mTracker->SyncNotifyProgress(FLAG_SIZE_AVAILABLE);
+ } else if (aType == imgINotificationObserver::FRAME_UPDATE) {
+ mTracker->SyncNotifyProgress(NoProgress, *aRect);
+ } else if (aType == imgINotificationObserver::FRAME_COMPLETE) {
+ mTracker->SyncNotifyProgress(FLAG_FRAME_COMPLETE);
+ } else if (aType == imgINotificationObserver::LOAD_COMPLETE) {
+ mTracker->SyncNotifyProgress(FLAG_LOAD_COMPLETE);
+ } else if (aType == imgINotificationObserver::DECODE_COMPLETE) {
+ mTracker->SyncNotifyProgress(FLAG_DECODE_COMPLETE);
+ } else if (aType == imgINotificationObserver::DISCARD) {
+ mTracker->OnDiscard();
+ } else if (aType == imgINotificationObserver::UNLOCKED_DRAW) {
+ mTracker->OnUnlockedDraw();
+ } else if (aType == imgINotificationObserver::IS_ANIMATED) {
+ mTracker->SyncNotifyProgress(FLAG_IS_ANIMATED);
+ } else if (aType == imgINotificationObserver::HAS_TRANSPARENCY) {
+ mTracker->SyncNotifyProgress(FLAG_HAS_TRANSPARENCY);
+ } else {
+ MOZ_ASSERT_UNREACHABLE("Notification list should be exhaustive");
+ }
+}
+
+void MultipartImage::OnLoadComplete(bool aLastPart) {
+ Progress progress = FLAG_LOAD_COMPLETE;
+ if (aLastPart) {
+ progress |= FLAG_LAST_PART_COMPLETE;
+ }
+ mTracker->SyncNotifyProgress(progress);
+}
+
+void MultipartImage::SetHasImage() { mTracker->OnImageAvailable(); }
+
+bool MultipartImage::NotificationsDeferred() const { return mPendingNotify; }
+
+void MultipartImage::MarkPendingNotify() { mPendingNotify = true; }
+
+void MultipartImage::ClearPendingNotify() { mPendingNotify = false; }
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/MultipartImage.h b/image/MultipartImage.h
new file mode 100644
index 0000000000..d4dbb845c0
--- /dev/null
+++ b/image/MultipartImage.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_MultipartImage_h
+#define mozilla_image_MultipartImage_h
+
+#include "ImageWrapper.h"
+#include "IProgressObserver.h"
+#include "ProgressTracker.h"
+
+namespace mozilla {
+namespace image {
+
+class NextPartObserver;
+
+/**
+ * An Image wrapper that implements support for multipart/x-mixed-replace
+ * images.
+ */
+class MultipartImage : public ImageWrapper, public IProgressObserver {
+ public:
+ MOZ_DECLARE_REFCOUNTED_TYPENAME(MultipartImage)
+ // We need to always declare refcounting here, because
+ // IProgressObserver has pure-virtual refcounting.
+ NS_DECL_ISUPPORTS_INHERITED
+
+ void BeginTransitionToPart(Image* aNextPart);
+
+ // Overridden ImageWrapper methods:
+ virtual already_AddRefed<imgIContainer> Unwrap() override;
+ virtual already_AddRefed<ProgressTracker> GetProgressTracker() override;
+ virtual void SetProgressTracker(ProgressTracker* aTracker) override;
+ virtual nsresult OnImageDataAvailable(nsIRequest* aRequest,
+ nsIInputStream* aInStr,
+ uint64_t aSourceOffset,
+ uint32_t aCount) override;
+ virtual nsresult OnImageDataComplete(nsIRequest* aRequest, nsresult aStatus,
+ bool aLastPart) override;
+
+ // We don't support locking or track animation consumers for individual parts,
+ // so we override these methods to do nothing.
+ NS_IMETHOD LockImage() override { return NS_OK; }
+ NS_IMETHOD UnlockImage() override { return NS_OK; }
+ virtual void IncrementAnimationConsumers() override {}
+ virtual void DecrementAnimationConsumers() override {}
+#ifdef DEBUG
+ virtual uint32_t GetAnimationConsumers() override { return 1; }
+#endif
+
+ // Overridden IProgressObserver methods:
+ virtual void Notify(int32_t aType, const nsIntRect* aRect = nullptr) override;
+ virtual void OnLoadComplete(bool aLastPart) override;
+ virtual void SetHasImage() override;
+ virtual bool NotificationsDeferred() const override;
+ virtual void MarkPendingNotify() override;
+ virtual void ClearPendingNotify() override;
+
+ protected:
+ virtual ~MultipartImage();
+
+ private:
+ friend class ImageFactory;
+ friend class NextPartObserver;
+
+ explicit MultipartImage(Image* aFirstPart);
+ void Init();
+
+ void FinishTransition();
+
+ RefPtr<ProgressTracker> mTracker;
+ RefPtr<NextPartObserver> mNextPartObserver;
+ RefPtr<Image> mNextPart;
+ bool mPendingNotify : 1;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_MultipartImage_h
diff --git a/image/Orientation.h b/image/Orientation.h
new file mode 100644
index 0000000000..e36a468372
--- /dev/null
+++ b/image/Orientation.h
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_Orientation_h
+#define mozilla_image_Orientation_h
+
+#include <stdint.h>
+#include "mozilla/gfx/Rect.h"
+
+namespace mozilla {
+
+// Pixel values in an image considering orientation metadata, such as the size
+// of an image as seen by consumers of the image.
+//
+// Any public methods on RasterImage that use untyped units are interpreted as
+// oriented pixels.
+struct OrientedPixel {};
+template <>
+struct IsPixel<OrientedPixel> : std::true_type {};
+typedef gfx::IntPointTyped<OrientedPixel> OrientedIntPoint;
+typedef gfx::IntSizeTyped<OrientedPixel> OrientedIntSize;
+typedef gfx::IntRectTyped<OrientedPixel> OrientedIntRect;
+
+// Pixel values in an image ignoring orientation metadata, such as are stored
+// in surfaces and the raw pixel data in the image.
+struct UnorientedPixel {};
+template <>
+struct IsPixel<UnorientedPixel> : std::true_type {};
+typedef gfx::IntPointTyped<UnorientedPixel> UnorientedIntPoint;
+typedef gfx::IntSizeTyped<UnorientedPixel> UnorientedIntSize;
+typedef gfx::IntRectTyped<UnorientedPixel> UnorientedIntRect;
+
+namespace image {
+
+enum class Angle : uint8_t { D0, D90, D180, D270 };
+
+enum class Flip : uint8_t { Unflipped, Horizontal };
+
+/**
+ * A struct that describes an image's orientation as a rotation optionally
+ * followed by a reflection. This may be used to be indicate an image's inherent
+ * orientation or a desired orientation for the image.
+ *
+ * When flipFirst = true, this indicates that the reflection is applied before
+ * the rotation. (This is used by OrientedImage to represent the inverse of an
+ * underlying image's Orientation.)
+ */
+struct Orientation {
+ explicit Orientation(Angle aRotation = Angle::D0,
+ Flip aFlip = Flip::Unflipped, bool aFlipFirst = false)
+ : rotation(aRotation), flip(aFlip), flipFirst(aFlipFirst) {}
+
+ Orientation Reversed() const {
+ return Orientation(InvertAngle(rotation), flip, !flipFirst);
+ }
+
+ bool IsIdentity() const {
+ return (rotation == Angle::D0) && (flip == Flip::Unflipped);
+ }
+
+ bool SwapsWidthAndHeight() const {
+ return (rotation == Angle::D90) || (rotation == Angle::D270);
+ }
+
+ bool operator==(const Orientation& aOther) const {
+ return rotation == aOther.rotation && flip == aOther.flip &&
+ flipFirst == aOther.flipFirst;
+ }
+
+ bool operator!=(const Orientation& aOther) const {
+ return !(*this == aOther);
+ }
+
+ OrientedIntSize ToOriented(const UnorientedIntSize& aSize) const {
+ if (SwapsWidthAndHeight()) {
+ return OrientedIntSize(aSize.height, aSize.width);
+ } else {
+ return OrientedIntSize(aSize.width, aSize.height);
+ }
+ }
+
+ UnorientedIntSize ToUnoriented(const OrientedIntSize& aSize) const {
+ if (SwapsWidthAndHeight()) {
+ return UnorientedIntSize(aSize.height, aSize.width);
+ } else {
+ return UnorientedIntSize(aSize.width, aSize.height);
+ }
+ }
+
+ static Angle InvertAngle(Angle aAngle) {
+ switch (aAngle) {
+ case Angle::D90:
+ return Angle::D270;
+ case Angle::D270:
+ return Angle::D90;
+ default:
+ return aAngle;
+ }
+ }
+
+ Angle rotation;
+ Flip flip;
+ bool flipFirst;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_Orientation_h
diff --git a/image/OrientedImage.cpp b/image/OrientedImage.cpp
new file mode 100644
index 0000000000..8461405dcb
--- /dev/null
+++ b/image/OrientedImage.cpp
@@ -0,0 +1,349 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "OrientedImage.h"
+
+#include <algorithm>
+
+#include "gfx2DGlue.h"
+#include "gfxContext.h"
+#include "gfxDrawable.h"
+#include "gfxPlatform.h"
+#include "gfxUtils.h"
+#include "ImageRegion.h"
+#include "mozilla/SVGImageContext.h"
+
+using std::swap;
+
+namespace mozilla {
+
+using namespace gfx;
+
+namespace image {
+
+NS_IMETHODIMP
+OrientedImage::GetWidth(int32_t* aWidth) {
+ if (mOrientation.SwapsWidthAndHeight()) {
+ return InnerImage()->GetHeight(aWidth);
+ } else {
+ return InnerImage()->GetWidth(aWidth);
+ }
+}
+
+NS_IMETHODIMP
+OrientedImage::GetHeight(int32_t* aHeight) {
+ if (mOrientation.SwapsWidthAndHeight()) {
+ return InnerImage()->GetWidth(aHeight);
+ } else {
+ return InnerImage()->GetHeight(aHeight);
+ }
+}
+
+nsresult OrientedImage::GetNativeSizes(nsTArray<IntSize>& aNativeSizes) {
+ nsresult rv = InnerImage()->GetNativeSizes(aNativeSizes);
+
+ if (mOrientation.SwapsWidthAndHeight()) {
+ auto i = aNativeSizes.Length();
+ while (i > 0) {
+ --i;
+ swap(aNativeSizes[i].width, aNativeSizes[i].height);
+ }
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP
+OrientedImage::GetIntrinsicSize(nsSize* aSize) {
+ nsresult rv = InnerImage()->GetIntrinsicSize(aSize);
+
+ if (mOrientation.SwapsWidthAndHeight()) {
+ swap(aSize->width, aSize->height);
+ }
+
+ return rv;
+}
+
+Maybe<AspectRatio> OrientedImage::GetIntrinsicRatio() {
+ Maybe<AspectRatio> ratio = InnerImage()->GetIntrinsicRatio();
+ if (ratio && mOrientation.SwapsWidthAndHeight()) {
+ ratio = Some(ratio->Inverted());
+ }
+ return ratio;
+}
+
+already_AddRefed<SourceSurface> OrientedImage::OrientSurface(
+ Orientation aOrientation, SourceSurface* aSurface) {
+ MOZ_ASSERT(aSurface);
+
+ // If the image does not require any re-orientation, return aSurface itself.
+ if (aOrientation.IsIdentity()) {
+ return do_AddRef(aSurface);
+ }
+
+ // Determine the size of the new surface.
+ nsIntSize originalSize = aSurface->GetSize();
+ nsIntSize targetSize = originalSize;
+ if (aOrientation.SwapsWidthAndHeight()) {
+ swap(targetSize.width, targetSize.height);
+ }
+
+ // Create our drawable.
+ RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(aSurface, originalSize);
+
+ // Determine an appropriate format for the surface.
+ gfx::SurfaceFormat surfaceFormat = IsOpaque(aSurface->GetFormat())
+ ? gfx::SurfaceFormat::OS_RGBX
+ : gfx::SurfaceFormat::OS_RGBA;
+
+ // Create the new surface to draw into.
+ RefPtr<DrawTarget> target =
+ gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
+ targetSize, surfaceFormat);
+ if (!target || !target->IsValid()) {
+ NS_ERROR("Could not create a DrawTarget");
+ return nullptr;
+ }
+
+ // Draw.
+ gfxContext ctx(target);
+
+ ctx.Multiply(OrientationMatrix(aOrientation, originalSize));
+ gfxUtils::DrawPixelSnapped(&ctx, drawable, SizeDouble(originalSize),
+ ImageRegion::Create(originalSize), surfaceFormat,
+ SamplingFilter::LINEAR);
+
+ return target->Snapshot();
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+OrientedImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) {
+ // Get a SourceSurface for the inner image then orient it according to
+ // mOrientation.
+ RefPtr<SourceSurface> innerSurface =
+ InnerImage()->GetFrame(aWhichFrame, aFlags);
+ NS_ENSURE_TRUE(innerSurface, nullptr);
+
+ return OrientSurface(mOrientation, innerSurface);
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+OrientedImage::GetFrameAtSize(const IntSize& aSize, uint32_t aWhichFrame,
+ uint32_t aFlags) {
+ // Get a SourceSurface for the inner image then orient it according to
+ // mOrientation.
+ IntSize innerSize = aSize;
+ if (mOrientation.SwapsWidthAndHeight()) {
+ swap(innerSize.width, innerSize.height);
+ }
+ RefPtr<SourceSurface> innerSurface =
+ InnerImage()->GetFrameAtSize(innerSize, aWhichFrame, aFlags);
+ NS_ENSURE_TRUE(innerSurface, nullptr);
+
+ return OrientSurface(mOrientation, innerSurface);
+}
+
+NS_IMETHODIMP_(bool)
+OrientedImage::IsImageContainerAvailable(WindowRenderer* aRenderer,
+ uint32_t aFlags) {
+ if (mOrientation.IsIdentity()) {
+ return InnerImage()->IsImageContainerAvailable(aRenderer, aFlags);
+ }
+ return false;
+}
+
+NS_IMETHODIMP_(ImgDrawResult)
+OrientedImage::GetImageProvider(WindowRenderer* aRenderer,
+ const gfx::IntSize& aSize,
+ const SVGImageContext& aSVGContext,
+ const Maybe<ImageIntRegion>& aRegion,
+ uint32_t aFlags,
+ WebRenderImageProvider** aProvider) {
+ // XXX(seth): We currently don't have a way of orienting the result of
+ // GetImageContainer. We work around this by always returning null, but if it
+ // ever turns out that OrientedImage is widely used on codepaths that can
+ // actually benefit from GetImageContainer, it would be a good idea to fix
+ // that method for performance reasons.
+
+ if (mOrientation.IsIdentity()) {
+ return InnerImage()->GetImageProvider(aRenderer, aSize, aSVGContext,
+ aRegion, aFlags, aProvider);
+ }
+
+ return ImgDrawResult::NOT_SUPPORTED;
+}
+
+struct MatrixBuilder {
+ explicit MatrixBuilder(bool aInvert) : mInvert(aInvert) {}
+
+ gfxMatrix Build() { return mMatrix; }
+
+ void Scale(gfxFloat aX, gfxFloat aY) {
+ if (mInvert) {
+ mMatrix *= gfxMatrix::Scaling(1.0 / aX, 1.0 / aY);
+ } else {
+ mMatrix.PreScale(aX, aY);
+ }
+ }
+
+ void Rotate(gfxFloat aPhi) {
+ if (mInvert) {
+ mMatrix *= gfxMatrix::Rotation(-aPhi);
+ } else {
+ mMatrix.PreRotate(aPhi);
+ }
+ }
+
+ void Translate(gfxPoint aDelta) {
+ if (mInvert) {
+ mMatrix *= gfxMatrix::Translation(-aDelta);
+ } else {
+ mMatrix.PreTranslate(aDelta);
+ }
+ }
+
+ private:
+ gfxMatrix mMatrix;
+ bool mInvert;
+};
+
+gfxMatrix OrientedImage::OrientationMatrix(Orientation aOrientation,
+ const nsIntSize& aSize,
+ bool aInvert /* = false */) {
+ MatrixBuilder builder(aInvert);
+
+ // Apply reflection, if present. (For a regular, non-flipFirst reflection,
+ // this logically happens second, but we apply it first because these
+ // transformations are all premultiplied.) A translation is necessary to place
+ // the image back in the first quadrant.
+ if (aOrientation.flip == Flip::Horizontal && !aOrientation.flipFirst) {
+ if (aOrientation.SwapsWidthAndHeight()) {
+ builder.Translate(gfxPoint(aSize.height, 0));
+ } else {
+ builder.Translate(gfxPoint(aSize.width, 0));
+ }
+ builder.Scale(-1.0, 1.0);
+ }
+
+ // Apply rotation, if present. Again, a translation is used to place the
+ // image back in the first quadrant.
+ switch (aOrientation.rotation) {
+ case Angle::D0:
+ break;
+ case Angle::D90:
+ builder.Translate(gfxPoint(aSize.height, 0));
+ builder.Rotate(-1.5 * M_PI);
+ break;
+ case Angle::D180:
+ builder.Translate(gfxPoint(aSize.width, aSize.height));
+ builder.Rotate(-1.0 * M_PI);
+ break;
+ case Angle::D270:
+ builder.Translate(gfxPoint(0, aSize.width));
+ builder.Rotate(-0.5 * M_PI);
+ break;
+ default:
+ MOZ_ASSERT(false, "Invalid rotation value");
+ }
+
+ // Apply a flipFirst reflection.
+ if (aOrientation.flip == Flip::Horizontal && aOrientation.flipFirst) {
+ builder.Translate(gfxPoint(aSize.width, 0.0));
+ builder.Scale(-1.0, 1.0);
+ }
+
+ return builder.Build();
+}
+
+NS_IMETHODIMP_(ImgDrawResult)
+OrientedImage::Draw(gfxContext* aContext, const nsIntSize& aSize,
+ const ImageRegion& aRegion, uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ const SVGImageContext& aSVGContext, uint32_t aFlags,
+ float aOpacity) {
+ if (mOrientation.IsIdentity()) {
+ return InnerImage()->Draw(aContext, aSize, aRegion, aWhichFrame,
+ aSamplingFilter, aSVGContext, aFlags, aOpacity);
+ }
+
+ // Update the image size to match the image's coordinate system. (This could
+ // be done using TransformBounds but since it's only a size a swap is enough.)
+ nsIntSize size(aSize);
+ if (mOrientation.SwapsWidthAndHeight()) {
+ swap(size.width, size.height);
+ }
+
+ // Update the matrix so that we transform the image into the orientation
+ // expected by the caller before drawing.
+ gfxMatrix matrix(OrientationMatrix(size));
+ gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
+ aContext->Multiply(matrix);
+
+ // The region is already in the orientation expected by the caller, but we
+ // need it to be in the image's coordinate system, so we transform it using
+ // the inverse of the orientation matrix.
+ gfxMatrix inverseMatrix(OrientationMatrix(size, /* aInvert = */ true));
+ ImageRegion region(aRegion);
+ region.TransformBoundsBy(inverseMatrix);
+
+ auto orientViewport = [&](const SVGImageContext& aOldContext) {
+ SVGImageContext context(aOldContext);
+ auto oldViewport = aOldContext.GetViewportSize();
+ if (oldViewport && mOrientation.SwapsWidthAndHeight()) {
+ // Swap width and height:
+ CSSIntSize newViewport(oldViewport->height, oldViewport->width);
+ context.SetViewportSize(Some(newViewport));
+ }
+ return context;
+ };
+
+ return InnerImage()->Draw(aContext, size, region, aWhichFrame,
+ aSamplingFilter, orientViewport(aSVGContext),
+ aFlags, aOpacity);
+}
+
+nsIntSize OrientedImage::OptimalImageSizeForDest(const gfxSize& aDest,
+ uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ uint32_t aFlags) {
+ if (!mOrientation.SwapsWidthAndHeight()) {
+ return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame,
+ aSamplingFilter, aFlags);
+ }
+
+ // Swap the size for the calculation, then swap it back for the caller.
+ gfxSize destSize(aDest.height, aDest.width);
+ nsIntSize innerImageSize(InnerImage()->OptimalImageSizeForDest(
+ destSize, aWhichFrame, aSamplingFilter, aFlags));
+ return nsIntSize(innerImageSize.height, innerImageSize.width);
+}
+
+NS_IMETHODIMP_(nsIntRect)
+OrientedImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect) {
+ nsIntRect rect(InnerImage()->GetImageSpaceInvalidationRect(aRect));
+
+ if (mOrientation.IsIdentity()) {
+ return rect;
+ }
+
+ nsIntSize innerSize;
+ nsresult rv = InnerImage()->GetWidth(&innerSize.width);
+ rv = NS_FAILED(rv) ? rv : InnerImage()->GetHeight(&innerSize.height);
+ if (NS_FAILED(rv)) {
+ // Fall back to identity if the width and height aren't available.
+ return rect;
+ }
+
+ // Transform the invalidation rect into the correct orientation.
+ gfxMatrix matrix(OrientationMatrix(innerSize));
+ gfxRect invalidRect(matrix.TransformBounds(
+ gfxRect(rect.X(), rect.Y(), rect.Width(), rect.Height())));
+
+ return IntRect::RoundOut(invalidRect.X(), invalidRect.Y(),
+ invalidRect.Width(), invalidRect.Height());
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/OrientedImage.h b/image/OrientedImage.h
new file mode 100644
index 0000000000..e01fcd639c
--- /dev/null
+++ b/image/OrientedImage.h
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_OrientedImage_h
+#define mozilla_image_OrientedImage_h
+
+#include "ImageWrapper.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
+#include "Orientation.h"
+
+namespace mozilla {
+namespace image {
+
+/**
+ * An Image wrapper that rotates and/or flips an image according to a specified
+ * Orientation.
+ *
+ * XXX(seth): There a known (performance, not correctness) issue with
+ * GetImageContainer. See the comments for that method for more information.
+ */
+class OrientedImage : public ImageWrapper {
+ typedef gfx::SourceSurface SourceSurface;
+
+ public:
+ NS_INLINE_DECL_REFCOUNTING_INHERITED(OrientedImage, ImageWrapper)
+
+ NS_IMETHOD GetWidth(int32_t* aWidth) override;
+ NS_IMETHOD GetHeight(int32_t* aHeight) override;
+ nsresult GetNativeSizes(nsTArray<gfx::IntSize>& aNativeSizes) override;
+ NS_IMETHOD GetIntrinsicSize(nsSize* aSize) override;
+ Maybe<AspectRatio> GetIntrinsicRatio() override;
+ NS_IMETHOD_(already_AddRefed<SourceSurface>)
+ GetFrame(uint32_t aWhichFrame, uint32_t aFlags) override;
+ NS_IMETHOD_(already_AddRefed<SourceSurface>)
+ GetFrameAtSize(const gfx::IntSize& aSize, uint32_t aWhichFrame,
+ uint32_t aFlags) override;
+ NS_IMETHOD_(bool)
+ IsImageContainerAvailable(WindowRenderer* aRenderer,
+ uint32_t aFlags) override;
+ NS_IMETHOD_(ImgDrawResult)
+ GetImageProvider(WindowRenderer* aRenderer, const gfx::IntSize& aSize,
+ const SVGImageContext& aSVGContext,
+ const Maybe<ImageIntRegion>& aRegion, uint32_t aFlags,
+ WebRenderImageProvider** aProvider) override;
+ NS_IMETHOD_(ImgDrawResult)
+ Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion,
+ uint32_t aWhichFrame, gfx::SamplingFilter aSamplingFilter,
+ const SVGImageContext& aSVGContext, uint32_t aFlags,
+ float aOpacity) override;
+ NS_IMETHOD_(nsIntRect)
+ GetImageSpaceInvalidationRect(const nsIntRect& aRect) override;
+ nsIntSize OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame,
+ gfx::SamplingFilter aSamplingFilter,
+ uint32_t aFlags) override;
+
+ /**
+ * Computes a matrix that applies the rotation and reflection specified by
+ * aOrientation, or that matrix's inverse if aInvert is true.
+ *
+ * @param aSize The scaled size of the inner image. (When outside code
+ * specifies the scaled size, as with imgIContainer::Draw and its aSize
+ * parameter, it's necessary to swap the width and height if
+ * mOrientation.SwapsWidthAndHeight() is true.)
+ *
+ * @param aInvert If true, compute the inverse of the orientation matrix.
+ * Prefer this approach to OrientationMatrix(..).Invert(), because it's more
+ * numerically accurate.
+ */
+ static gfxMatrix OrientationMatrix(Orientation aOrientation,
+ const nsIntSize& aSize,
+ bool aInvert = false);
+
+ /**
+ * Returns a SourceSurface that is the result of rotating and flipping
+ * aSurface according to aOrientation.
+ */
+ static already_AddRefed<SourceSurface> OrientSurface(Orientation aOrientation,
+ SourceSurface* aSurface);
+
+ protected:
+ OrientedImage(Image* aImage, Orientation aOrientation)
+ : ImageWrapper(aImage), mOrientation(aOrientation) {}
+
+ virtual ~OrientedImage() {}
+
+ gfxMatrix OrientationMatrix(const nsIntSize& aSize, bool aInvert = false) {
+ return OrientationMatrix(mOrientation, aSize, aInvert);
+ }
+
+ private:
+ Orientation mOrientation;
+
+ friend class ImageOps;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_OrientedImage_h
diff --git a/image/PlaybackType.h b/image/PlaybackType.h
new file mode 100644
index 0000000000..ff820ca680
--- /dev/null
+++ b/image/PlaybackType.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_PlaybackType_h
+#define mozilla_image_PlaybackType_h
+
+#include "imgIContainer.h"
+
+namespace mozilla {
+namespace image {
+
+/**
+ * PlaybackType identifies a surface cache entry as either a static surface or
+ * an animation. Note that a specific cache entry is one or the other, but
+ * images may be associated with both types of cache entries, since in some
+ * circumstances we may want to treat an animated image as if it were static.
+ */
+enum class PlaybackType : uint8_t {
+ eStatic, // Calls to DrawableRef() will always return the same surface.
+ eAnimated // An animation; calls to DrawableRef() may return different
+ // surfaces at different times.
+};
+
+/**
+ * Given an imgIContainer FRAME_* value, returns the corresponding PlaybackType
+ * for use in surface cache lookups.
+ */
+inline PlaybackType ToPlaybackType(uint32_t aWhichFrame) {
+ MOZ_ASSERT(aWhichFrame == imgIContainer::FRAME_FIRST ||
+ aWhichFrame == imgIContainer::FRAME_CURRENT);
+ return aWhichFrame == imgIContainer::FRAME_CURRENT ? PlaybackType::eAnimated
+ : PlaybackType::eStatic;
+}
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_PlaybackType_h
diff --git a/image/ProgressTracker.cpp b/image/ProgressTracker.cpp
new file mode 100644
index 0000000000..2d8720fa76
--- /dev/null
+++ b/image/ProgressTracker.cpp
@@ -0,0 +1,561 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageLogging.h"
+#include "ProgressTracker.h"
+
+#include "imgINotificationObserver.h"
+#include "imgIRequest.h"
+#include "Image.h"
+#include "nsNetUtil.h"
+#include "nsIObserverService.h"
+
+#include "mozilla/AppShutdown.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/Services.h"
+
+using mozilla::WeakPtr;
+
+namespace mozilla {
+namespace image {
+
+static void CheckProgressConsistency(Progress aOldProgress,
+ Progress aNewProgress, bool aIsMultipart) {
+ // Check preconditions for every progress bit.
+
+ // Error's do not get propagated from the tracker for each image part to the
+ // tracker for the multipart image because we don't want one bad part to
+ // prevent the remaining parts from showing. So we need to consider whether
+ // this is a tracker for a multipart image for these assertions to work.
+
+ if (aNewProgress & FLAG_SIZE_AVAILABLE) {
+ // No preconditions.
+ }
+ if (aNewProgress & FLAG_DECODE_COMPLETE) {
+ MOZ_ASSERT(aNewProgress & FLAG_SIZE_AVAILABLE);
+ MOZ_ASSERT(aIsMultipart ||
+ aNewProgress & (FLAG_FRAME_COMPLETE | FLAG_HAS_ERROR));
+ }
+ if (aNewProgress & FLAG_FRAME_COMPLETE) {
+ MOZ_ASSERT(aNewProgress & FLAG_SIZE_AVAILABLE);
+ }
+ if (aNewProgress & FLAG_LOAD_COMPLETE) {
+ MOZ_ASSERT(aIsMultipart ||
+ aNewProgress & (FLAG_SIZE_AVAILABLE | FLAG_HAS_ERROR));
+ }
+ if (aNewProgress & FLAG_IS_ANIMATED) {
+ // No preconditions; like FLAG_HAS_TRANSPARENCY, we should normally never
+ // discover this *after* FLAG_SIZE_AVAILABLE, but unfortunately some corrupt
+ // GIFs may fool us.
+ }
+ if (aNewProgress & FLAG_HAS_TRANSPARENCY) {
+ // XXX We'd like to assert that transparency is only set during metadata
+ // decode but we don't have any way to assert that until bug 1254892 is
+ // fixed.
+ }
+ if (aNewProgress & FLAG_LAST_PART_COMPLETE) {
+ MOZ_ASSERT(aNewProgress & FLAG_LOAD_COMPLETE);
+ }
+ if (aNewProgress & FLAG_HAS_ERROR) {
+ // No preconditions.
+ }
+}
+
+ProgressTracker::ProgressTracker()
+ : mMutex("ProgressTracker::mMutex"),
+ mImage(nullptr),
+ mEventTarget(WrapNotNull(
+ nsCOMPtr<nsIEventTarget>(GetMainThreadSerialEventTarget()))),
+ mObserversWithTargets(0),
+ mObservers(new ObserverTable),
+ mProgress(NoProgress),
+ mIsMultipart(false) {}
+
+void ProgressTracker::SetImage(Image* aImage) {
+ MutexAutoLock lock(mMutex);
+ MOZ_ASSERT(aImage, "Setting null image");
+ MOZ_ASSERT(!mImage, "Setting image when we already have one");
+ mImage = aImage;
+}
+
+void ProgressTracker::ResetImage() {
+ MutexAutoLock lock(mMutex);
+ MOZ_ASSERT(mImage, "Resetting image when it's already null!");
+ mImage = nullptr;
+}
+
+uint32_t ProgressTracker::GetImageStatus() const {
+ uint32_t status = imgIRequest::STATUS_NONE;
+
+ // Translate our current state to a set of imgIRequest::STATE_* flags.
+ if (mProgress & FLAG_SIZE_AVAILABLE) {
+ status |= imgIRequest::STATUS_SIZE_AVAILABLE;
+ }
+ if (mProgress & FLAG_DECODE_COMPLETE) {
+ status |= imgIRequest::STATUS_DECODE_COMPLETE;
+ }
+ if (mProgress & FLAG_FRAME_COMPLETE) {
+ status |= imgIRequest::STATUS_FRAME_COMPLETE;
+ }
+ if (mProgress & FLAG_LOAD_COMPLETE) {
+ status |= imgIRequest::STATUS_LOAD_COMPLETE;
+ }
+ if (mProgress & FLAG_IS_ANIMATED) {
+ status |= imgIRequest::STATUS_IS_ANIMATED;
+ }
+ if (mProgress & FLAG_HAS_TRANSPARENCY) {
+ status |= imgIRequest::STATUS_HAS_TRANSPARENCY;
+ }
+ if (mProgress & FLAG_HAS_ERROR) {
+ status |= imgIRequest::STATUS_ERROR;
+ }
+
+ return status;
+}
+
+// A helper class to allow us to call SyncNotify asynchronously.
+class AsyncNotifyRunnable : public Runnable {
+ public:
+ AsyncNotifyRunnable(ProgressTracker* aTracker, IProgressObserver* aObserver)
+ : Runnable("ProgressTracker::AsyncNotifyRunnable"), mTracker(aTracker) {
+ MOZ_ASSERT(NS_IsMainThread(), "Should be created on the main thread");
+ MOZ_ASSERT(aTracker, "aTracker should not be null");
+ MOZ_ASSERT(aObserver, "aObserver should not be null");
+ mObservers.AppendElement(aObserver);
+ }
+
+ NS_IMETHOD Run() override {
+ MOZ_ASSERT(NS_IsMainThread(), "Should be running on the main thread");
+ MOZ_ASSERT(mTracker, "mTracker should not be null");
+ for (uint32_t i = 0; i < mObservers.Length(); ++i) {
+ mObservers[i]->ClearPendingNotify();
+ mTracker->SyncNotify(mObservers[i]);
+ }
+
+ mTracker->mRunnable = nullptr;
+ return NS_OK;
+ }
+
+ void AddObserver(IProgressObserver* aObserver) {
+ mObservers.AppendElement(aObserver);
+ }
+
+ void RemoveObserver(IProgressObserver* aObserver) {
+ mObservers.RemoveElement(aObserver);
+ }
+
+ private:
+ friend class ProgressTracker;
+
+ RefPtr<ProgressTracker> mTracker;
+ nsTArray<RefPtr<IProgressObserver>> mObservers;
+};
+
+ProgressTracker::RenderBlockingRunnable::RenderBlockingRunnable(
+ already_AddRefed<AsyncNotifyRunnable>&& aEvent)
+ : PrioritizableRunnable(std::move(aEvent),
+ nsIRunnablePriority::PRIORITY_RENDER_BLOCKING) {}
+
+void ProgressTracker::RenderBlockingRunnable::AddObserver(
+ IProgressObserver* aObserver) {
+ static_cast<AsyncNotifyRunnable*>(mRunnable.get())->AddObserver(aObserver);
+}
+
+void ProgressTracker::RenderBlockingRunnable::RemoveObserver(
+ IProgressObserver* aObserver) {
+ static_cast<AsyncNotifyRunnable*>(mRunnable.get())->RemoveObserver(aObserver);
+}
+
+/* static */
+already_AddRefed<ProgressTracker::RenderBlockingRunnable>
+ProgressTracker::RenderBlockingRunnable::Create(
+ already_AddRefed<AsyncNotifyRunnable>&& aEvent) {
+ MOZ_ASSERT(NS_IsMainThread());
+ RefPtr<ProgressTracker::RenderBlockingRunnable> event(
+ new ProgressTracker::RenderBlockingRunnable(std::move(aEvent)));
+ return event.forget();
+}
+
+void ProgressTracker::Notify(IProgressObserver* aObserver) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (aObserver->NotificationsDeferred()) {
+ // There is a pending notification, or the observer isn't ready yet.
+ return;
+ }
+
+ if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) {
+ RefPtr<Image> image = GetImage();
+ LOG_FUNC_WITH_PARAM(gImgLog, "ProgressTracker::Notify async", "uri", image);
+ }
+
+ aObserver->MarkPendingNotify();
+
+ // If we have an existing runnable that we can use, we just append this
+ // observer to its list of observers to be notified. This ensures we don't
+ // unnecessarily delay onload.
+ if (mRunnable) {
+ mRunnable->AddObserver(aObserver);
+ } else if (!AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownThreads)) {
+ // Avoid dispatch if we are late in shutdown.
+ RefPtr<AsyncNotifyRunnable> ev = new AsyncNotifyRunnable(this, aObserver);
+ mRunnable = ProgressTracker::RenderBlockingRunnable::Create(ev.forget());
+ mEventTarget->Dispatch(mRunnable, NS_DISPATCH_NORMAL);
+ }
+}
+
+// A helper class to allow us to call SyncNotify asynchronously for a given,
+// fixed, state.
+class AsyncNotifyCurrentStateRunnable : public Runnable {
+ public:
+ AsyncNotifyCurrentStateRunnable(ProgressTracker* aProgressTracker,
+ IProgressObserver* aObserver)
+ : Runnable("image::AsyncNotifyCurrentStateRunnable"),
+ mProgressTracker(aProgressTracker),
+ mObserver(aObserver) {
+ MOZ_ASSERT(NS_IsMainThread(), "Should be created on the main thread");
+ MOZ_ASSERT(mProgressTracker, "mProgressTracker should not be null");
+ MOZ_ASSERT(mObserver, "mObserver should not be null");
+ mImage = mProgressTracker->GetImage();
+ }
+
+ NS_IMETHOD Run() override {
+ MOZ_ASSERT(NS_IsMainThread(), "Should be running on the main thread");
+ mObserver->ClearPendingNotify();
+
+ mProgressTracker->SyncNotify(mObserver);
+ return NS_OK;
+ }
+
+ private:
+ RefPtr<ProgressTracker> mProgressTracker;
+ RefPtr<IProgressObserver> mObserver;
+
+ // We have to hold on to a reference to the tracker's image, just in case
+ // it goes away while we're in the event queue.
+ RefPtr<Image> mImage;
+};
+
+void ProgressTracker::NotifyCurrentState(IProgressObserver* aObserver) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (aObserver->NotificationsDeferred()) {
+ // There is a pending notification, or the observer isn't ready yet.
+ return;
+ }
+
+ if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) {
+ RefPtr<Image> image = GetImage();
+ LOG_FUNC_WITH_PARAM(gImgLog, "ProgressTracker::NotifyCurrentState", "uri",
+ image);
+ }
+
+ aObserver->MarkPendingNotify();
+
+ // Avoid dispatch if we are late in shutdown.
+ if (!AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownThreads)) {
+ nsCOMPtr<nsIRunnable> ev =
+ new AsyncNotifyCurrentStateRunnable(this, aObserver);
+ mEventTarget->Dispatch(ev.forget(), NS_DISPATCH_NORMAL);
+ }
+}
+
+/**
+ * ImageObserverNotifier is a helper type that abstracts over the difference
+ * between sending notifications to all of the observers in an ObserverTable,
+ * and sending them to a single observer. This allows the same notification code
+ * to be used for both cases.
+ */
+template <typename T>
+struct ImageObserverNotifier;
+
+template <>
+struct MOZ_STACK_CLASS ImageObserverNotifier<const ObserverTable*> {
+ explicit ImageObserverNotifier(const ObserverTable* aObservers,
+ bool aIgnoreDeferral = false)
+ : mObservers(aObservers), mIgnoreDeferral(aIgnoreDeferral) {}
+
+ template <typename Lambda>
+ void operator()(Lambda aFunc) {
+ for (const auto& weakObserver : mObservers->Values()) {
+ RefPtr<IProgressObserver> observer = weakObserver.get();
+ if (observer && (mIgnoreDeferral || !observer->NotificationsDeferred())) {
+ aFunc(observer);
+ }
+ }
+ }
+
+ private:
+ const ObserverTable* mObservers;
+ const bool mIgnoreDeferral;
+};
+
+template <>
+struct MOZ_STACK_CLASS ImageObserverNotifier<IProgressObserver*> {
+ explicit ImageObserverNotifier(IProgressObserver* aObserver)
+ : mObserver(aObserver) {}
+
+ template <typename Lambda>
+ void operator()(Lambda aFunc) {
+ if (mObserver && !mObserver->NotificationsDeferred()) {
+ aFunc(mObserver);
+ }
+ }
+
+ private:
+ IProgressObserver* mObserver;
+};
+
+template <typename T>
+void SyncNotifyInternal(const T& aObservers, bool aHasImage, Progress aProgress,
+ const nsIntRect& aDirtyRect) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ typedef imgINotificationObserver I;
+ ImageObserverNotifier<T> notify(aObservers);
+
+ if (aProgress & FLAG_SIZE_AVAILABLE) {
+ notify([](IProgressObserver* aObs) { aObs->Notify(I::SIZE_AVAILABLE); });
+ }
+
+ if (aHasImage) {
+ // OnFrameUpdate
+ // If there's any content in this frame at all (always true for
+ // vector images, true for raster images that have decoded at
+ // least one frame) then send OnFrameUpdate.
+ if (!aDirtyRect.IsEmpty()) {
+ notify([&](IProgressObserver* aObs) {
+ aObs->Notify(I::FRAME_UPDATE, &aDirtyRect);
+ });
+ }
+
+ if (aProgress & FLAG_FRAME_COMPLETE) {
+ notify([](IProgressObserver* aObs) { aObs->Notify(I::FRAME_COMPLETE); });
+ }
+
+ if (aProgress & FLAG_HAS_TRANSPARENCY) {
+ notify(
+ [](IProgressObserver* aObs) { aObs->Notify(I::HAS_TRANSPARENCY); });
+ }
+
+ if (aProgress & FLAG_IS_ANIMATED) {
+ notify([](IProgressObserver* aObs) { aObs->Notify(I::IS_ANIMATED); });
+ }
+ }
+
+ if (aProgress & FLAG_DECODE_COMPLETE) {
+ MOZ_ASSERT(aHasImage, "Stopped decoding without ever having an image?");
+ notify([](IProgressObserver* aObs) { aObs->Notify(I::DECODE_COMPLETE); });
+ }
+
+ if (aProgress & FLAG_LOAD_COMPLETE) {
+ notify([=](IProgressObserver* aObs) {
+ aObs->OnLoadComplete(aProgress & FLAG_LAST_PART_COMPLETE);
+ });
+ }
+}
+
+void ProgressTracker::SyncNotifyProgress(Progress aProgress,
+ const nsIntRect& aInvalidRect
+ /* = nsIntRect() */) {
+ MOZ_ASSERT(NS_IsMainThread(), "Use mObservers on main thread only");
+
+ Progress progress = Difference(aProgress);
+ CheckProgressConsistency(mProgress, mProgress | progress, mIsMultipart);
+
+ // Apply the changes.
+ mProgress |= progress;
+
+ // Send notifications.
+ mObservers.Read([&](const ObserverTable* aTable) {
+ SyncNotifyInternal(aTable, HasImage(), progress, aInvalidRect);
+ });
+
+ if (progress & FLAG_HAS_ERROR) {
+ FireFailureNotification();
+ }
+}
+
+void ProgressTracker::SyncNotify(IProgressObserver* aObserver) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ RefPtr<Image> image = GetImage();
+ LOG_SCOPE_WITH_PARAM(gImgLog, "ProgressTracker::SyncNotify", "uri", image);
+
+ nsIntRect rect;
+ if (image) {
+ int32_t width, height;
+ if (NS_FAILED(image->GetWidth(&width)) ||
+ NS_FAILED(image->GetHeight(&height))) {
+ // Either the image has no intrinsic size, or it has an error.
+ rect = GetMaxSizedIntRect();
+ } else {
+ rect.SizeTo(width, height);
+ }
+ }
+
+ SyncNotifyInternal(aObserver, !!image, mProgress, rect);
+}
+
+void ProgressTracker::EmulateRequestFinished(IProgressObserver* aObserver) {
+ MOZ_ASSERT(NS_IsMainThread(),
+ "SyncNotifyState and mObservers are not threadsafe");
+ RefPtr<IProgressObserver> kungFuDeathGrip(aObserver);
+
+ if (!(mProgress & FLAG_LOAD_COMPLETE)) {
+ aObserver->OnLoadComplete(true);
+ }
+}
+
+already_AddRefed<nsIEventTarget> ProgressTracker::GetEventTarget() const {
+ MutexAutoLock lock(mMutex);
+ nsCOMPtr<nsIEventTarget> target = mEventTarget;
+ return target.forget();
+}
+
+void ProgressTracker::AddObserver(IProgressObserver* aObserver) {
+ MOZ_ASSERT(NS_IsMainThread());
+ RefPtr<IProgressObserver> observer = aObserver;
+
+ nsCOMPtr<nsIEventTarget> target = observer->GetEventTarget();
+ if (target) {
+ if (mObserversWithTargets == 0) {
+ // On the first observer with a target (i.e. listener), always accept its
+ // event target; this may be for a specific DocGroup, or it may be the
+ // unlabelled main thread target.
+ MutexAutoLock lock(mMutex);
+ mEventTarget = WrapNotNull(target);
+ } else if (mEventTarget.get() != target.get()) {
+ // If a subsequent observer comes in with a different target, we need to
+ // switch to use the unlabelled main thread target, if we haven't already.
+ MutexAutoLock lock(mMutex);
+ nsCOMPtr<nsIEventTarget> mainTarget(do_GetMainThread());
+ mEventTarget = WrapNotNull(mainTarget);
+ }
+ ++mObserversWithTargets;
+ }
+
+ mObservers.Write([=](ObserverTable* aTable) {
+ MOZ_ASSERT(!aTable->Contains(observer),
+ "Adding duplicate entry for image observer");
+
+ WeakPtr<IProgressObserver> weakPtr = observer.get();
+ aTable->InsertOrUpdate(observer, weakPtr);
+ });
+
+ MOZ_ASSERT(mObserversWithTargets <= ObserverCount());
+}
+
+bool ProgressTracker::RemoveObserver(IProgressObserver* aObserver) {
+ MOZ_ASSERT(NS_IsMainThread());
+ RefPtr<IProgressObserver> observer = aObserver;
+
+ // Remove the observer from the list.
+ bool removed = mObservers.Write(
+ [observer](ObserverTable* aTable) { return aTable->Remove(observer); });
+
+ // Sometimes once an image is decoded, and all of its observers removed, a new
+ // document may request the same image. Thus we need to clear our event target
+ // state when the last observer is removed, so that we select the most
+ // appropriate event target when a new observer is added. Since the event
+ // target may have changed (e.g. due to the scheduler group going away before
+ // we were removed), so we should be cautious comparing this target against
+ // anything at this stage.
+ if (removed) {
+ nsCOMPtr<nsIEventTarget> target = observer->GetEventTarget();
+ if (target) {
+ MOZ_ASSERT(mObserversWithTargets > 0);
+ --mObserversWithTargets;
+
+ // If we're shutting down there's no need to update event targets.
+ if ((mObserversWithTargets == 0) &&
+ !AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownThreads)) {
+ MutexAutoLock lock(mMutex);
+ nsCOMPtr<nsIEventTarget> target(do_GetMainThread());
+ mEventTarget = WrapNotNull(target);
+ }
+ }
+
+ MOZ_ASSERT(mObserversWithTargets <= ObserverCount());
+ }
+
+ // Observers can get confused if they don't get all the proper teardown
+ // notifications. Part ways on good terms.
+ if (removed && !aObserver->NotificationsDeferred()) {
+ EmulateRequestFinished(aObserver);
+ }
+
+ // Make sure we don't give callbacks to an observer that isn't interested in
+ // them any more.
+ if (aObserver->NotificationsDeferred() && mRunnable) {
+ mRunnable->RemoveObserver(aObserver);
+ aObserver->ClearPendingNotify();
+ }
+
+ return removed;
+}
+
+uint32_t ProgressTracker::ObserverCount() const {
+ MOZ_ASSERT(NS_IsMainThread());
+ return mObservers.Read(
+ [](const ObserverTable* aTable) { return aTable->Count(); });
+}
+
+void ProgressTracker::OnUnlockedDraw() {
+ MOZ_ASSERT(NS_IsMainThread());
+ mObservers.Read([](const ObserverTable* aTable) {
+ ImageObserverNotifier<const ObserverTable*> notify(aTable);
+ notify([](IProgressObserver* aObs) {
+ aObs->Notify(imgINotificationObserver::UNLOCKED_DRAW);
+ });
+ });
+}
+
+void ProgressTracker::ResetForNewRequest() {
+ MOZ_ASSERT(NS_IsMainThread());
+ mProgress = NoProgress;
+}
+
+void ProgressTracker::OnDiscard() {
+ MOZ_ASSERT(NS_IsMainThread());
+ mObservers.Read([](const ObserverTable* aTable) {
+ ImageObserverNotifier<const ObserverTable*> notify(aTable);
+ notify([](IProgressObserver* aObs) {
+ aObs->Notify(imgINotificationObserver::DISCARD);
+ });
+ });
+}
+
+void ProgressTracker::OnImageAvailable() {
+ MOZ_ASSERT(NS_IsMainThread());
+ // Notify any imgRequestProxys that are observing us that we have an Image.
+ mObservers.Read([](const ObserverTable* aTable) {
+ ImageObserverNotifier<const ObserverTable*> notify(
+ aTable, /* aIgnoreDeferral = */ true);
+ notify([](IProgressObserver* aObs) { aObs->SetHasImage(); });
+ });
+}
+
+void ProgressTracker::FireFailureNotification() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ // Some kind of problem has happened with image decoding.
+ // Report the URI to net:failed-to-process-uri-conent observers.
+ RefPtr<Image> image = GetImage();
+ if (image) {
+ // Should be on main thread, so ok to create a new nsIURI.
+ nsCOMPtr<nsIURI> uri = image->GetURI();
+ if (uri) {
+ nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+ if (os) {
+ os->NotifyObservers(uri, "net:failed-to-process-uri-content", nullptr);
+ }
+ }
+ }
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/ProgressTracker.h b/image/ProgressTracker.h
new file mode 100644
index 0000000000..568fb5e28c
--- /dev/null
+++ b/image/ProgressTracker.h
@@ -0,0 +1,264 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_ProgressTracker_h
+#define mozilla_image_ProgressTracker_h
+
+#include "CopyOnWrite.h"
+#include "mozilla/NotNull.h"
+#include "mozilla/Mutex.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/WeakPtr.h"
+#include "nsTHashMap.h"
+#include "nsCOMPtr.h"
+#include "nsTObserverArray.h"
+#include "nsThreadUtils.h"
+#include "nsRect.h"
+#include "IProgressObserver.h"
+
+class nsIRunnable;
+
+namespace mozilla {
+namespace image {
+
+class AsyncNotifyRunnable;
+class AsyncNotifyCurrentStateRunnable;
+class Image;
+
+/**
+ * Image progress bitflags.
+ *
+ * See CheckProgressConsistency() for the invariants we enforce about the
+ * ordering dependencies between these flags.
+ */
+enum {
+ FLAG_SIZE_AVAILABLE = 1u << 0, // STATUS_SIZE_AVAILABLE
+ FLAG_DECODE_COMPLETE = 1u << 1, // STATUS_DECODE_COMPLETE
+ FLAG_FRAME_COMPLETE = 1u << 2, // STATUS_FRAME_COMPLETE
+ FLAG_LOAD_COMPLETE = 1u << 3, // STATUS_LOAD_COMPLETE
+ FLAG_IS_ANIMATED = 1u << 6, // STATUS_IS_ANIMATED
+ FLAG_HAS_TRANSPARENCY = 1u << 7, // STATUS_HAS_TRANSPARENCY
+ FLAG_LAST_PART_COMPLETE = 1u << 8,
+ FLAG_HAS_ERROR = 1u << 9 // STATUS_ERROR
+};
+
+typedef uint32_t Progress;
+
+const uint32_t NoProgress = 0;
+
+inline Progress LoadCompleteProgress(bool aLastPart, bool aError,
+ nsresult aStatus) {
+ Progress progress = FLAG_LOAD_COMPLETE;
+ if (aLastPart) {
+ progress |= FLAG_LAST_PART_COMPLETE;
+ }
+ if (NS_FAILED(aStatus) || aError) {
+ progress |= FLAG_HAS_ERROR;
+ }
+ return progress;
+}
+
+/**
+ * ProgressTracker stores its observers in an ObserverTable, which is a hash
+ * table mapping raw pointers to WeakPtr's to the same objects. This sounds like
+ * unnecessary duplication of information, but it's necessary for stable hash
+ * values since WeakPtr's lose the knowledge of which object they used to point
+ * to when that object is destroyed.
+ *
+ * ObserverTable subclasses nsTHashMap to add reference counting
+ * support and a copy constructor, both of which are needed for use with
+ * CopyOnWrite<T>.
+ */
+class ObserverTable : public nsTHashMap<nsPtrHashKey<IProgressObserver>,
+ WeakPtr<IProgressObserver>> {
+ public:
+ NS_INLINE_DECL_REFCOUNTING(ObserverTable);
+
+ ObserverTable() = default;
+
+ ObserverTable(const ObserverTable& aOther)
+ : nsTHashMap<nsPtrHashKey<IProgressObserver>, WeakPtr<IProgressObserver>>(
+ aOther.Clone()) {
+ NS_WARNING("Forced to copy ObserverTable due to nested notifications");
+ }
+
+ private:
+ ~ObserverTable() {}
+};
+
+/**
+ * ProgressTracker is a class that records an Image's progress through the
+ * loading and decoding process, and makes it possible to send notifications to
+ * IProgressObservers, both synchronously and asynchronously.
+ *
+ * When a new observer needs to be notified of the current progress of an image,
+ * call the Notify() method on this class with the relevant observer as its
+ * argument, and the notifications will be replayed to the observer
+ * asynchronously.
+ */
+class ProgressTracker : public mozilla::SupportsWeakPtr {
+ virtual ~ProgressTracker() {}
+
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ProgressTracker)
+
+ ProgressTracker();
+
+ bool HasImage() const {
+ MutexAutoLock lock(mMutex);
+ return mImage;
+ }
+ already_AddRefed<Image> GetImage() const {
+ MutexAutoLock lock(mMutex);
+ RefPtr<Image> image = mImage;
+ return image.forget();
+ }
+
+ // Get the current image status (as in imgIRequest).
+ uint32_t GetImageStatus() const;
+
+ // Get the current Progress.
+ Progress GetProgress() const { return mProgress; }
+
+ // Schedule an asynchronous "replaying" of all the notifications that would
+ // have to happen to put us in the current state.
+ // We will also take note of any notifications that happen between the time
+ // Notify() is called and when we call SyncNotify on |aObserver|, and replay
+ // them as well.
+ // Should be called on the main thread only, since observers and GetURI are
+ // not threadsafe.
+ void Notify(IProgressObserver* aObserver);
+
+ // Schedule an asynchronous "replaying" of all the notifications that would
+ // have to happen to put us in the state we are in right now.
+ // Unlike Notify(), does *not* take into account future notifications.
+ // This is only useful if you do not have an imgRequest, e.g., if you are a
+ // static request returned from imgIRequest::GetStaticRequest().
+ // Should be called on the main thread only, since observers and GetURI are
+ // not threadsafe.
+ void NotifyCurrentState(IProgressObserver* aObserver);
+
+ // "Replay" all of the notifications that would have to happen to put us in
+ // the state we're currently in.
+ // Only use this if you're already servicing an asynchronous call (e.g.
+ // OnStartRequest).
+ // Should be called on the main thread only, since observers and GetURI are
+ // not threadsafe.
+ void SyncNotify(IProgressObserver* aObserver);
+
+ // Get this ProgressTracker ready for a new request. This resets all the
+ // state that doesn't persist between requests.
+ void ResetForNewRequest();
+
+ // Stateless notifications. These are dispatched and immediately forgotten
+ // about. All of these notifications are main thread only.
+ void OnDiscard();
+ void OnUnlockedDraw();
+ void OnImageAvailable();
+
+ // Compute the difference between this our progress and aProgress. This allows
+ // callers to predict whether SyncNotifyProgress will send any notifications.
+ Progress Difference(Progress aProgress) const {
+ return ~mProgress & aProgress;
+ }
+
+ // Update our state to incorporate the changes in aProgress and synchronously
+ // notify our observers.
+ //
+ // Because this may result in recursive notifications, no decoding locks may
+ // be held. Called on the main thread only.
+ void SyncNotifyProgress(Progress aProgress,
+ const nsIntRect& aInvalidRect = nsIntRect());
+
+ // We manage a set of observers that are using an image and thus concerned
+ // with its loading progress. Weak pointers.
+ void AddObserver(IProgressObserver* aObserver);
+ bool RemoveObserver(IProgressObserver* aObserver);
+ uint32_t ObserverCount() const;
+
+ // Get the event target we should currently dispatch events to.
+ already_AddRefed<nsIEventTarget> GetEventTarget() const;
+
+ // Resets our weak reference to our image. Image subclasses should call this
+ // in their destructor.
+ void ResetImage();
+
+ // Tell this progress tracker that it is for a multipart image.
+ void SetIsMultipart() { mIsMultipart = true; }
+
+ private:
+ friend class AsyncNotifyRunnable;
+ friend class AsyncNotifyCurrentStateRunnable;
+ friend class ImageFactory;
+
+ ProgressTracker(const ProgressTracker& aOther) = delete;
+
+ // Sets our weak reference to our image. Only ImageFactory should call this.
+ void SetImage(Image* aImage);
+
+ // Send some notifications that would be necessary to make |aObserver| believe
+ // the request is finished downloading and decoding. We only send
+ // FLAG_LOAD_COMPLETE and FLAG_ONLOAD_UNBLOCKED, and only if necessary.
+ void EmulateRequestFinished(IProgressObserver* aObserver);
+
+ // Main thread only because it deals with the observer service.
+ void FireFailureNotification();
+
+ // Wrapper for AsyncNotifyRunnable to make it have medium high priority like
+ // other imagelib runnables.
+ class RenderBlockingRunnable final : public PrioritizableRunnable {
+ explicit RenderBlockingRunnable(
+ already_AddRefed<AsyncNotifyRunnable>&& aEvent);
+ virtual ~RenderBlockingRunnable() = default;
+
+ public:
+ void AddObserver(IProgressObserver* aObserver);
+ void RemoveObserver(IProgressObserver* aObserver);
+
+ static already_AddRefed<RenderBlockingRunnable> Create(
+ already_AddRefed<AsyncNotifyRunnable>&& aEvent);
+ };
+
+ // The runnable, if any, that we've scheduled to deliver async notifications.
+ RefPtr<RenderBlockingRunnable> mRunnable;
+
+ // mMutex protects access to mImage and mEventTarget.
+ mutable Mutex mMutex MOZ_UNANNOTATED;
+
+ // mImage is a weak ref; it should be set to null when the image goes out of
+ // scope.
+ Image* mImage;
+
+ // mEventTarget is the current, best effort event target to dispatch
+ // notifications to from the decoder threads. It will change as observers are
+ // added and removed (see mObserversWithTargets).
+ NotNull<nsCOMPtr<nsIEventTarget>> mEventTarget;
+
+ // How many observers have been added that have an explicit event target.
+ // When the first observer is added with an explicit event target, we will
+ // default to that as long as all observers use the same target. If a new
+ // observer is added which has a different event target, we will switch to
+ // using the unlabeled main thread event target which is safe for all
+ // observers. If all observers with explicit event targets are removed, we
+ // will revert back to the initial event target (for SystemGroup). An
+ // observer without an explicit event target does not care what context it
+ // is dispatched in, and thus does not impact the state.
+ uint32_t mObserversWithTargets;
+
+ // Hashtable of observers attached to the image. Each observer represents a
+ // consumer using the image. Main thread only.
+ CopyOnWrite<ObserverTable> mObservers;
+
+ Progress mProgress;
+
+ // Whether this is a progress tracker for a multipart image.
+ bool mIsMultipart;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_ProgressTracker_h
diff --git a/image/RasterImage.cpp b/image/RasterImage.cpp
new file mode 100644
index 0000000000..775238b460
--- /dev/null
+++ b/image/RasterImage.cpp
@@ -0,0 +1,1785 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Must #include ImageLogging.h before any IPDL-generated files or other files
+// that #include prlog.h
+#include "RasterImage.h"
+
+#include <stdint.h>
+
+#include <algorithm>
+#include <utility>
+
+#include "DecodePool.h"
+#include "Decoder.h"
+#include "FrameAnimator.h"
+#include "GeckoProfiler.h"
+#include "IDecodingTask.h"
+#include "ImageLogging.h"
+#include "ImageRegion.h"
+#include "LookupResult.h"
+#include "OrientedImage.h"
+#include "SourceBuffer.h"
+#include "SurfaceCache.h"
+#include "gfx2DGlue.h"
+#include "gfxContext.h"
+#include "gfxPlatform.h"
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/DebugOnly.h"
+#include "mozilla/Likely.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/SizeOfState.h"
+#include "mozilla/StaticPrefs_image.h"
+#include "mozilla/Telemetry.h"
+#include "mozilla/TimeStamp.h"
+
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Scale.h"
+#include "nsComponentManagerUtils.h"
+#include "nsError.h"
+#include "nsIConsoleService.h"
+#include "nsIInputStream.h"
+#include "nsIScriptError.h"
+#include "nsISupportsPrimitives.h"
+#include "nsMemory.h"
+#include "nsPresContext.h"
+#include "nsProperties.h"
+#include "prenv.h"
+#include "prsystem.h"
+#include "WindowRenderer.h"
+
+namespace mozilla {
+
+using namespace gfx;
+using namespace layers;
+
+namespace image {
+
+using std::ceil;
+using std::min;
+
+#ifndef DEBUG
+NS_IMPL_ISUPPORTS(RasterImage, imgIContainer)
+#else
+NS_IMPL_ISUPPORTS(RasterImage, imgIContainer, imgIContainerDebug)
+#endif
+
+//******************************************************************************
+RasterImage::RasterImage(nsIURI* aURI /* = nullptr */)
+ : ImageResource(aURI), // invoke superclass's constructor
+ mSize(0, 0),
+ mLockCount(0),
+ mDecoderType(DecoderType::UNKNOWN),
+ mDecodeCount(0),
+#ifdef DEBUG
+ mFramesNotified(0),
+#endif
+ mSourceBuffer(MakeNotNull<SourceBuffer*>()) {
+}
+
+//******************************************************************************
+RasterImage::~RasterImage() {
+ // Make sure our SourceBuffer is marked as complete. This will ensure that any
+ // outstanding decoders terminate.
+ if (!mSourceBuffer->IsComplete()) {
+ mSourceBuffer->Complete(NS_ERROR_ABORT);
+ }
+
+ // Release all frames from the surface cache.
+ SurfaceCache::RemoveImage(ImageKey(this));
+
+ // Record Telemetry.
+ Telemetry::Accumulate(Telemetry::IMAGE_DECODE_COUNT, mDecodeCount);
+}
+
+nsresult RasterImage::Init(const char* aMimeType, uint32_t aFlags) {
+ // We don't support re-initialization
+ if (mInitialized) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ // Not sure an error can happen before init, but be safe
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // We want to avoid redecodes for transient images.
+ MOZ_ASSERT_IF(aFlags & INIT_FLAG_TRANSIENT,
+ !(aFlags & INIT_FLAG_DISCARDABLE));
+
+ // Store initialization data
+ StoreDiscardable(!!(aFlags & INIT_FLAG_DISCARDABLE));
+ StoreWantFullDecode(!!(aFlags & INIT_FLAG_DECODE_IMMEDIATELY));
+ StoreTransient(!!(aFlags & INIT_FLAG_TRANSIENT));
+ StoreSyncLoad(!!(aFlags & INIT_FLAG_SYNC_LOAD));
+
+ // Use the MIME type to select a decoder type, and make sure there *is* a
+ // decoder for this MIME type.
+ NS_ENSURE_ARG_POINTER(aMimeType);
+ mDecoderType = DecoderFactory::GetDecoderType(aMimeType);
+ if (mDecoderType == DecoderType::UNKNOWN) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Lock this image's surfaces in the SurfaceCache if we're not discardable.
+ if (!LoadDiscardable()) {
+ mLockCount++;
+ SurfaceCache::LockImage(ImageKey(this));
+ }
+
+ // Set the default flags according to the decoder type to allow preferences to
+ // be stored if necessary.
+ mDefaultDecoderFlags =
+ DecoderFactory::GetDefaultDecoderFlagsForType(mDecoderType);
+
+ // Mark us as initialized
+ mInitialized = true;
+
+ return NS_OK;
+}
+
+//******************************************************************************
+NS_IMETHODIMP_(void)
+RasterImage::RequestRefresh(const TimeStamp& aTime) {
+ if (HadRecentRefresh(aTime)) {
+ return;
+ }
+
+ EvaluateAnimation();
+
+ if (!mAnimating) {
+ return;
+ }
+
+ RefreshResult res;
+ if (mAnimationState) {
+ MOZ_ASSERT(mFrameAnimator);
+ res = mFrameAnimator->RequestRefresh(*mAnimationState, aTime);
+ }
+
+#ifdef DEBUG
+ if (res.mFrameAdvanced) {
+ mFramesNotified++;
+ }
+#endif
+
+ // Notify listeners that our frame has actually changed, but do this only
+ // once for all frames that we've now passed (if AdvanceFrame() was called
+ // more than once).
+ if (!res.mDirtyRect.IsEmpty() || res.mFrameAdvanced) {
+ auto dirtyRect = OrientedIntRect::FromUnknownRect(res.mDirtyRect);
+ NotifyProgress(NoProgress, dirtyRect);
+ }
+
+ if (res.mAnimationFinished) {
+ StoreAnimationFinished(true);
+ EvaluateAnimation();
+ }
+}
+
+//******************************************************************************
+NS_IMETHODIMP
+RasterImage::GetWidth(int32_t* aWidth) {
+ NS_ENSURE_ARG_POINTER(aWidth);
+
+ if (mError) {
+ *aWidth = 0;
+ return NS_ERROR_FAILURE;
+ }
+
+ *aWidth = mSize.width;
+ return NS_OK;
+}
+
+//******************************************************************************
+NS_IMETHODIMP
+RasterImage::GetHeight(int32_t* aHeight) {
+ NS_ENSURE_ARG_POINTER(aHeight);
+
+ if (mError) {
+ *aHeight = 0;
+ return NS_ERROR_FAILURE;
+ }
+
+ *aHeight = mSize.height;
+ return NS_OK;
+}
+
+//******************************************************************************
+void RasterImage::MediaFeatureValuesChangedAllDocuments(
+ const mozilla::MediaFeatureChange& aChange) {}
+
+//******************************************************************************
+nsresult RasterImage::GetNativeSizes(nsTArray<IntSize>& aNativeSizes) {
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ aNativeSizes.Clear();
+
+ if (mNativeSizes.IsEmpty()) {
+ aNativeSizes.AppendElement(mSize.ToUnknownSize());
+ } else {
+ for (const auto& size : mNativeSizes) {
+ aNativeSizes.AppendElement(size.ToUnknownSize());
+ }
+ }
+
+ return NS_OK;
+}
+
+//******************************************************************************
+size_t RasterImage::GetNativeSizesLength() {
+ if (mError || !LoadHasSize()) {
+ return 0;
+ }
+
+ if (mNativeSizes.IsEmpty()) {
+ return 1;
+ }
+
+ return mNativeSizes.Length();
+}
+
+//******************************************************************************
+NS_IMETHODIMP
+RasterImage::GetIntrinsicSize(nsSize* aSize) {
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ *aSize = nsSize(nsPresContext::CSSPixelsToAppUnits(mSize.width),
+ nsPresContext::CSSPixelsToAppUnits(mSize.height));
+ return NS_OK;
+}
+
+//******************************************************************************
+Maybe<AspectRatio> RasterImage::GetIntrinsicRatio() {
+ if (mError) {
+ return Nothing();
+ }
+
+ return Some(AspectRatio::FromSize(mSize.width, mSize.height));
+}
+
+NS_IMETHODIMP_(Orientation)
+RasterImage::GetOrientation() { return mOrientation; }
+
+NS_IMETHODIMP_(Resolution)
+RasterImage::GetResolution() { return mResolution; }
+
+//******************************************************************************
+NS_IMETHODIMP
+RasterImage::GetType(uint16_t* aType) {
+ NS_ENSURE_ARG_POINTER(aType);
+
+ *aType = imgIContainer::TYPE_RASTER;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+RasterImage::GetProviderId(uint32_t* aId) {
+ NS_ENSURE_ARG_POINTER(aId);
+
+ *aId = ImageResource::GetImageProviderId();
+ return NS_OK;
+}
+
+LookupResult RasterImage::LookupFrameInternal(const OrientedIntSize& aSize,
+ uint32_t aFlags,
+ PlaybackType aPlaybackType,
+ bool aMarkUsed) {
+ if (mAnimationState && aPlaybackType == PlaybackType::eAnimated) {
+ MOZ_ASSERT(mFrameAnimator);
+ MOZ_ASSERT(ToSurfaceFlags(aFlags) == DefaultSurfaceFlags(),
+ "Can't composite frames with non-default surface flags");
+ return mFrameAnimator->GetCompositedFrame(*mAnimationState, aMarkUsed);
+ }
+
+ SurfaceFlags surfaceFlags = ToSurfaceFlags(aFlags);
+
+ // We don't want any substitution for sync decodes, and substitution would be
+ // illegal when high quality downscaling is disabled, so we use
+ // SurfaceCache::Lookup in this case.
+ if ((aFlags & FLAG_SYNC_DECODE) || !(aFlags & FLAG_HIGH_QUALITY_SCALING)) {
+ return SurfaceCache::Lookup(
+ ImageKey(this),
+ RasterSurfaceKey(aSize.ToUnknownSize(), surfaceFlags,
+ PlaybackType::eStatic),
+ aMarkUsed);
+ }
+
+ // We'll return the best match we can find to the requested frame.
+ return SurfaceCache::LookupBestMatch(
+ ImageKey(this),
+ RasterSurfaceKey(aSize.ToUnknownSize(), surfaceFlags,
+ PlaybackType::eStatic),
+ aMarkUsed);
+}
+
+LookupResult RasterImage::LookupFrame(const OrientedIntSize& aSize,
+ uint32_t aFlags,
+ PlaybackType aPlaybackType,
+ bool aMarkUsed) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ // If we're opaque, we don't need to care about premultiplied alpha, because
+ // that can only matter for frames with transparency.
+ if (IsOpaque()) {
+ aFlags &= ~FLAG_DECODE_NO_PREMULTIPLY_ALPHA;
+ }
+
+ OrientedIntSize requestedSize =
+ CanDownscaleDuringDecode(aSize, aFlags) ? aSize : mSize;
+ if (requestedSize.IsEmpty()) {
+ // Can't decode to a surface of zero size.
+ return LookupResult(MatchType::NOT_FOUND);
+ }
+
+ LookupResult result =
+ LookupFrameInternal(requestedSize, aFlags, aPlaybackType, aMarkUsed);
+
+ if (!result && !LoadHasSize()) {
+ // We can't request a decode without knowing our intrinsic size. Give up.
+ return LookupResult(MatchType::NOT_FOUND);
+ }
+
+ // We want to trigger a decode if and only if:
+ // 1) There is no pending decode
+ // 2) There is no acceptable size decoded
+ // 3) The pending decode has not produced a frame yet, a sync decode is
+ // requested, and we have all the source data. Without the source data, we
+ // will just trigger another async decode anyways.
+ //
+ // TODO(aosmond): We should better handle case 3. We should actually return
+ // TEMPORARY_ERROR or NOT_READY if we don't have all the source data and a
+ // sync decode is requested. If there is a pending decode and we have all the
+ // source data, we should always be able to block on the frame's monitor --
+ // perhaps this could be accomplished by preallocating the first frame buffer
+ // when we create the decoder.
+ const bool syncDecode = aFlags & FLAG_SYNC_DECODE;
+ const bool avoidRedecode = aFlags & FLAG_AVOID_REDECODE_FOR_SIZE;
+ if (result.Type() == MatchType::NOT_FOUND ||
+ (result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND &&
+ !avoidRedecode) ||
+ (syncDecode && !avoidRedecode && !result && LoadAllSourceData())) {
+ // We don't have a copy of this frame, and there's no decoder working on
+ // one. (Or we're sync decoding and the existing decoder hasn't even started
+ // yet.) Trigger decoding so it'll be available next time.
+ MOZ_ASSERT(aPlaybackType != PlaybackType::eAnimated ||
+ StaticPrefs::image_mem_animated_discardable_AtStartup() ||
+ !mAnimationState || mAnimationState->KnownFrameCount() < 1,
+ "Animated frames should be locked");
+
+ // The surface cache may suggest the preferred size we are supposed to
+ // decode at. This should only happen if we accept substitutions.
+ if (!result.SuggestedSize().IsEmpty()) {
+ MOZ_ASSERT(!syncDecode && (aFlags & FLAG_HIGH_QUALITY_SCALING));
+ requestedSize = OrientedIntSize::FromUnknownSize(result.SuggestedSize());
+ }
+
+ bool ranSync = false, failed = false;
+ Decode(requestedSize, aFlags, aPlaybackType, ranSync, failed);
+ if (failed) {
+ result.SetFailedToRequestDecode();
+ }
+
+ // If we can or did sync decode, we should already have the frame.
+ if (ranSync || syncDecode) {
+ result =
+ LookupFrameInternal(requestedSize, aFlags, aPlaybackType, aMarkUsed);
+ }
+ }
+
+ if (!result) {
+ // We still weren't able to get a frame. Give up.
+ return result;
+ }
+
+ // Sync decoding guarantees that we got the frame, but if it's owned by an
+ // async decoder that's currently running, the contents of the frame may not
+ // be available yet. Make sure we get everything.
+ if (LoadAllSourceData() && syncDecode) {
+ result.Surface()->WaitUntilFinished();
+ }
+
+ // If we could have done some decoding in this function we need to check if
+ // that decoding encountered an error and hence aborted the surface. We want
+ // to avoid calling IsAborted if we weren't passed any sync decode flag
+ // because IsAborted acquires the monitor for the imgFrame.
+ if (aFlags & (FLAG_SYNC_DECODE | FLAG_SYNC_DECODE_IF_FAST) &&
+ result.Surface()->IsAborted()) {
+ DrawableSurface tmp = std::move(result.Surface());
+ return result;
+ }
+
+ return result;
+}
+
+bool RasterImage::IsOpaque() {
+ if (mError) {
+ return false;
+ }
+
+ Progress progress = mProgressTracker->GetProgress();
+
+ // If we haven't yet finished decoding, the safe answer is "not opaque".
+ if (!(progress & FLAG_DECODE_COMPLETE)) {
+ return false;
+ }
+
+ // Other, we're opaque if FLAG_HAS_TRANSPARENCY is not set.
+ return !(progress & FLAG_HAS_TRANSPARENCY);
+}
+
+NS_IMETHODIMP_(bool)
+RasterImage::WillDrawOpaqueNow() {
+ if (!IsOpaque()) {
+ return false;
+ }
+
+ if (mAnimationState) {
+ if (!StaticPrefs::image_mem_animated_discardable_AtStartup()) {
+ // We never discard frames of animated images.
+ return true;
+ } else {
+ if (mAnimationState->GetCompositedFrameInvalid()) {
+ // We're not going to draw anything at all.
+ return false;
+ }
+ }
+ }
+
+ // If we are not locked our decoded data could get discard at any time (ie
+ // between the call to this function and when we are asked to draw), so we
+ // have to return false if we are unlocked.
+ if (mLockCount == 0) {
+ return false;
+ }
+
+ LookupResult result = SurfaceCache::LookupBestMatch(
+ ImageKey(this),
+ RasterSurfaceKey(mSize.ToUnknownSize(), DefaultSurfaceFlags(),
+ PlaybackType::eStatic),
+ /* aMarkUsed = */ false);
+ MatchType matchType = result.Type();
+ if (matchType == MatchType::NOT_FOUND || matchType == MatchType::PENDING ||
+ !result.Surface()->IsFinished()) {
+ return false;
+ }
+
+ return true;
+}
+
+void RasterImage::OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) {
+ MOZ_ASSERT(mProgressTracker);
+
+ bool animatedFramesDiscarded =
+ mAnimationState && aSurfaceKey.Playback() == PlaybackType::eAnimated;
+
+ nsCOMPtr<nsIEventTarget> eventTarget;
+ if (mProgressTracker) {
+ eventTarget = mProgressTracker->GetEventTarget();
+ } else {
+ eventTarget = do_GetMainThread();
+ }
+
+ RefPtr<RasterImage> image = this;
+ nsCOMPtr<nsIRunnable> ev =
+ NS_NewRunnableFunction("RasterImage::OnSurfaceDiscarded", [=]() -> void {
+ image->OnSurfaceDiscardedInternal(animatedFramesDiscarded);
+ });
+ eventTarget->Dispatch(ev.forget(), NS_DISPATCH_NORMAL);
+}
+
+void RasterImage::OnSurfaceDiscardedInternal(bool aAnimatedFramesDiscarded) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (aAnimatedFramesDiscarded && mAnimationState) {
+ MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable_AtStartup());
+
+ IntRect rect = mAnimationState->UpdateState(this, mSize.ToUnknownSize());
+
+ auto dirtyRect = OrientedIntRect::FromUnknownRect(rect);
+ NotifyProgress(NoProgress, dirtyRect);
+ }
+
+ if (mProgressTracker) {
+ mProgressTracker->OnDiscard();
+ }
+}
+
+//******************************************************************************
+NS_IMETHODIMP
+RasterImage::GetAnimated(bool* aAnimated) {
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ NS_ENSURE_ARG_POINTER(aAnimated);
+
+ // If we have an AnimationState, we can know for sure.
+ if (mAnimationState) {
+ *aAnimated = true;
+ return NS_OK;
+ }
+
+ // Otherwise, we need to have been decoded to know for sure, since if we were
+ // decoded at least once mAnimationState would have been created for animated
+ // images. This is true even though we check for animation during the
+ // metadata decode, because we may still discover animation only during the
+ // full decode for corrupt images.
+ if (!LoadHasBeenDecoded()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ // We know for sure
+ *aAnimated = false;
+
+ return NS_OK;
+}
+
+//******************************************************************************
+NS_IMETHODIMP_(int32_t)
+RasterImage::GetFirstFrameDelay() {
+ if (mError) {
+ return -1;
+ }
+
+ bool animated = false;
+ if (NS_FAILED(GetAnimated(&animated)) || !animated) {
+ return -1;
+ }
+
+ MOZ_ASSERT(mAnimationState, "Animated images should have an AnimationState");
+ return mAnimationState->FirstFrameTimeout().AsEncodedValueDeprecated();
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+RasterImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) {
+ return GetFrameAtSize(mSize.ToUnknownSize(), aWhichFrame, aFlags);
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+RasterImage::GetFrameAtSize(const IntSize& aSize, uint32_t aWhichFrame,
+ uint32_t aFlags) {
+ MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
+
+ AutoProfilerImagePaintMarker PROFILER_RAII(this);
+#ifdef DEBUG
+ NotifyDrawingObservers();
+#endif
+
+ if (aSize.IsEmpty() || aWhichFrame > FRAME_MAX_VALUE || mError) {
+ return nullptr;
+ }
+
+ auto size = OrientedIntSize::FromUnknownSize(aSize);
+
+ // Get the frame. If it's not there, it's probably the caller's fault for
+ // not waiting for the data to be loaded from the network or not passing
+ // FLAG_SYNC_DECODE.
+ LookupResult result = LookupFrame(size, aFlags, ToPlaybackType(aWhichFrame),
+ /* aMarkUsed = */ true);
+ if (!result) {
+ // The OS threw this frame away and we couldn't redecode it.
+ return nullptr;
+ }
+
+ return result.Surface()->GetSourceSurface();
+}
+
+NS_IMETHODIMP_(bool)
+RasterImage::IsImageContainerAvailable(WindowRenderer* aRenderer,
+ uint32_t aFlags) {
+ return LoadHasSize();
+}
+
+NS_IMETHODIMP_(ImgDrawResult)
+RasterImage::GetImageProvider(WindowRenderer* aRenderer,
+ const gfx::IntSize& aSize,
+ const SVGImageContext& aSVGContext,
+ const Maybe<ImageIntRegion>& aRegion,
+ uint32_t aFlags,
+ WebRenderImageProvider** aProvider) {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(aRenderer);
+
+ if (mError) {
+ return ImgDrawResult::BAD_IMAGE;
+ }
+
+ if (!LoadHasSize()) {
+ return ImgDrawResult::NOT_READY;
+ }
+
+ if (aSize.IsEmpty()) {
+ return ImgDrawResult::BAD_ARGS;
+ }
+
+ // We check the minimum size because while we support downscaling, we do not
+ // support upscaling. If aRequestedSize > mSize, we will never give a larger
+ // surface than mSize. If mSize > aRequestedSize, and mSize > maxTextureSize,
+ // we still want to use image containers if aRequestedSize <= maxTextureSize.
+ int32_t maxTextureSize = aRenderer->GetMaxTextureSize();
+ if (min(mSize.width, aSize.width) > maxTextureSize ||
+ min(mSize.height, aSize.height) > maxTextureSize) {
+ return ImgDrawResult::NOT_SUPPORTED;
+ }
+
+ AutoProfilerImagePaintMarker PROFILER_RAII(this);
+#ifdef DEBUG
+ NotifyDrawingObservers();
+#endif
+
+ // Get the frame. If it's not there, it's probably the caller's fault for
+ // not waiting for the data to be loaded from the network or not passing
+ // FLAG_SYNC_DECODE.
+ LookupResult result = LookupFrame(OrientedIntSize::FromUnknownSize(aSize),
+ aFlags, PlaybackType::eAnimated,
+ /* aMarkUsed = */ true);
+ if (!result) {
+ // The OS threw this frame away and we couldn't redecode it.
+ return ImgDrawResult::NOT_READY;
+ }
+
+ if (!result.Surface()->IsFinished()) {
+ result.Surface().TakeProvider(aProvider);
+ return ImgDrawResult::INCOMPLETE;
+ }
+
+ result.Surface().TakeProvider(aProvider);
+ switch (result.Type()) {
+ case MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND:
+ case MatchType::SUBSTITUTE_BECAUSE_PENDING:
+ return ImgDrawResult::WRONG_SIZE;
+ default:
+ return ImgDrawResult::SUCCESS;
+ }
+}
+
+size_t RasterImage::SizeOfSourceWithComputedFallback(
+ SizeOfState& aState) const {
+ return mSourceBuffer->SizeOfIncludingThisWithComputedFallback(
+ aState.mMallocSizeOf);
+}
+
+bool RasterImage::SetMetadata(const ImageMetadata& aMetadata,
+ bool aFromMetadataDecode) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (mError) {
+ return true;
+ }
+
+ mResolution = aMetadata.GetResolution();
+
+ if (aMetadata.HasSize()) {
+ auto metadataSize = aMetadata.GetSize();
+ if (metadataSize.width < 0 || metadataSize.height < 0) {
+ NS_WARNING("Image has negative intrinsic size");
+ DoError();
+ return true;
+ }
+
+ MOZ_ASSERT(aMetadata.HasOrientation());
+ Orientation orientation = aMetadata.GetOrientation();
+
+ // If we already have a size, check the new size against the old one.
+ if (LoadHasSize() &&
+ (metadataSize != mSize || orientation != mOrientation)) {
+ NS_WARNING(
+ "Image changed size or orientation on redecode! "
+ "This should not happen!");
+ DoError();
+ return true;
+ }
+
+ // Set the size and flag that we have it.
+ mOrientation = orientation;
+ mSize = metadataSize;
+ mNativeSizes.Clear();
+ for (const auto& nativeSize : aMetadata.GetNativeSizes()) {
+ mNativeSizes.AppendElement(nativeSize);
+ }
+ StoreHasSize(true);
+ }
+
+ if (LoadHasSize() && aMetadata.HasAnimation() && !mAnimationState) {
+ // We're becoming animated, so initialize animation stuff.
+ mAnimationState.emplace(mAnimationMode);
+ mFrameAnimator = MakeUnique<FrameAnimator>(this, mSize.ToUnknownSize());
+
+ if (!StaticPrefs::image_mem_animated_discardable_AtStartup()) {
+ // We don't support discarding animated images (See bug 414259).
+ // Lock the image and throw away the key.
+ LockImage();
+ }
+
+ if (!aFromMetadataDecode) {
+ // The metadata decode reported that this image isn't animated, but we
+ // discovered that it actually was during the full decode. This is a
+ // rare failure that only occurs for corrupt images. To recover, we need
+ // to discard all existing surfaces and redecode.
+ return false;
+ }
+ }
+
+ if (mAnimationState) {
+ mAnimationState->SetLoopCount(aMetadata.GetLoopCount());
+ mAnimationState->SetFirstFrameTimeout(aMetadata.GetFirstFrameTimeout());
+
+ if (aMetadata.HasLoopLength()) {
+ mAnimationState->SetLoopLength(aMetadata.GetLoopLength());
+ }
+ if (aMetadata.HasFirstFrameRefreshArea()) {
+ mAnimationState->SetFirstFrameRefreshArea(
+ aMetadata.GetFirstFrameRefreshArea());
+ }
+ }
+
+ if (aMetadata.HasHotspot()) {
+ // NOTE(heycam): We shouldn't have any image formats that support both
+ // orientation and hotspots, so we assert that rather than add code
+ // to orient the hotspot point correctly.
+ MOZ_ASSERT(mOrientation.IsIdentity(), "Would need to orient hotspot point");
+
+ auto hotspot = aMetadata.GetHotspot();
+ mHotspot.x = std::max(std::min(hotspot.x.value, mSize.width - 1), 0);
+ mHotspot.y = std::max(std::min(hotspot.y.value, mSize.height - 1), 0);
+ }
+
+ return true;
+}
+
+NS_IMETHODIMP
+RasterImage::SetAnimationMode(uint16_t aAnimationMode) {
+ if (mAnimationState) {
+ mAnimationState->SetAnimationMode(aAnimationMode);
+ }
+ return SetAnimationModeInternal(aAnimationMode);
+}
+
+//******************************************************************************
+
+nsresult RasterImage::StartAnimation() {
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ MOZ_ASSERT(ShouldAnimate(), "Should not animate!");
+
+ // If we're not ready to animate, then set mPendingAnimation, which will cause
+ // us to start animating if and when we do become ready.
+ StorePendingAnimation(!mAnimationState ||
+ mAnimationState->KnownFrameCount() < 1);
+ if (LoadPendingAnimation()) {
+ return NS_OK;
+ }
+
+ // Don't bother to animate if we're displaying the first frame forever.
+ if (mAnimationState->GetCurrentAnimationFrameIndex() == 0 &&
+ mAnimationState->FirstFrameTimeout() == FrameTimeout::Forever()) {
+ StoreAnimationFinished(true);
+ return NS_ERROR_ABORT;
+ }
+
+ // We need to set the time that this initial frame was first displayed, as
+ // this is used in AdvanceFrame().
+ mAnimationState->InitAnimationFrameTimeIfNecessary();
+
+ return NS_OK;
+}
+
+//******************************************************************************
+nsresult RasterImage::StopAnimation() {
+ MOZ_ASSERT(mAnimating, "Should be animating!");
+
+ nsresult rv = NS_OK;
+ if (mError) {
+ rv = NS_ERROR_FAILURE;
+ } else {
+ mAnimationState->SetAnimationFrameTime(TimeStamp());
+ }
+
+ mAnimating = false;
+ return rv;
+}
+
+//******************************************************************************
+NS_IMETHODIMP
+RasterImage::ResetAnimation() {
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ StorePendingAnimation(false);
+
+ if (mAnimationMode == kDontAnimMode || !mAnimationState ||
+ mAnimationState->GetCurrentAnimationFrameIndex() == 0) {
+ return NS_OK;
+ }
+
+ StoreAnimationFinished(false);
+
+ if (mAnimating) {
+ StopAnimation();
+ }
+
+ MOZ_ASSERT(mAnimationState, "Should have AnimationState");
+ MOZ_ASSERT(mFrameAnimator, "Should have FrameAnimator");
+ mFrameAnimator->ResetAnimation(*mAnimationState);
+
+ IntRect area = mAnimationState->FirstFrameRefreshArea();
+ NotifyProgress(NoProgress, OrientedIntRect::FromUnknownRect(area));
+
+ // Start the animation again. It may not have been running before, if
+ // mAnimationFinished was true before entering this function.
+ EvaluateAnimation();
+
+ return NS_OK;
+}
+
+//******************************************************************************
+NS_IMETHODIMP_(void)
+RasterImage::SetAnimationStartTime(const TimeStamp& aTime) {
+ if (mError || mAnimationMode == kDontAnimMode || mAnimating ||
+ !mAnimationState) {
+ return;
+ }
+
+ mAnimationState->SetAnimationFrameTime(aTime);
+}
+
+NS_IMETHODIMP_(float)
+RasterImage::GetFrameIndex(uint32_t aWhichFrame) {
+ MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE, "Invalid argument");
+ return (aWhichFrame == FRAME_FIRST || !mAnimationState)
+ ? 0.0f
+ : mAnimationState->GetCurrentAnimationFrameIndex();
+}
+
+NS_IMETHODIMP_(IntRect)
+RasterImage::GetImageSpaceInvalidationRect(const IntRect& aRect) {
+ // Note that we do not transform aRect into an UnorientedIntRect, since
+ // RasterImage::NotifyProgress notifies all consumers of the image using
+ // OrientedIntRect values. (This is unlike OrientedImage, which notifies
+ // using inner image coordinates.)
+ return aRect;
+}
+
+nsresult RasterImage::OnImageDataComplete(nsIRequest*, nsresult aStatus,
+ bool aLastPart) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ // Record that we have all the data we're going to get now.
+ StoreAllSourceData(true);
+
+ // Let decoders know that there won't be any more data coming.
+ mSourceBuffer->Complete(aStatus);
+
+ // Allow a synchronous metadata decode if mSyncLoad was set, or if we're
+ // running on a single thread (in which case waiting for the async metadata
+ // decoder could delay this image's load event quite a bit), or if this image
+ // is transient.
+ bool canSyncDecodeMetadata =
+ LoadSyncLoad() || LoadTransient() || DecodePool::NumberOfCores() < 2;
+
+ if (canSyncDecodeMetadata && !LoadHasSize()) {
+ // We're loading this image synchronously, so it needs to be usable after
+ // this call returns. Since we haven't gotten our size yet, we need to do a
+ // synchronous metadata decode here.
+ DecodeMetadata(FLAG_SYNC_DECODE);
+ }
+
+ // Determine our final status, giving precedence to Necko failure codes. We
+ // check after running the metadata decode in case it triggered an error.
+ nsresult finalStatus = mError ? NS_ERROR_FAILURE : NS_OK;
+ if (NS_FAILED(aStatus)) {
+ finalStatus = aStatus;
+ }
+
+ // If loading failed, report an error.
+ if (NS_FAILED(finalStatus)) {
+ DoError();
+ }
+
+ Progress loadProgress = LoadCompleteProgress(aLastPart, mError, finalStatus);
+
+ if (!LoadHasSize() && !mError) {
+ // We don't have our size yet, so we'll fire the load event in SetSize().
+ MOZ_ASSERT(!canSyncDecodeMetadata,
+ "Firing load async after metadata sync decode?");
+ mLoadProgress = Some(loadProgress);
+ return finalStatus;
+ }
+
+ NotifyForLoadEvent(loadProgress);
+
+ return finalStatus;
+}
+
+void RasterImage::NotifyForLoadEvent(Progress aProgress) {
+ MOZ_ASSERT(LoadHasSize() || mError,
+ "Need to know size before firing load event");
+ MOZ_ASSERT(
+ !LoadHasSize() || (mProgressTracker->GetProgress() & FLAG_SIZE_AVAILABLE),
+ "Should have notified that the size is available if we have it");
+
+ // If we encountered an error, make sure we notify for that as well.
+ if (mError) {
+ aProgress |= FLAG_HAS_ERROR;
+ }
+
+ // Notify our listeners, which will fire this image's load event.
+ NotifyProgress(aProgress);
+}
+
+nsresult RasterImage::OnImageDataAvailable(nsIRequest*,
+ nsIInputStream* aInputStream,
+ uint64_t, uint32_t aCount) {
+ nsresult rv = mSourceBuffer->AppendFromInputStream(aInputStream, aCount);
+ if (NS_SUCCEEDED(rv) && !LoadSomeSourceData()) {
+ StoreSomeSourceData(true);
+ if (!LoadSyncLoad()) {
+ // Create an async metadata decoder and verify we succeed in doing so.
+ rv = DecodeMetadata(DECODE_FLAGS_DEFAULT);
+ }
+ }
+
+ if (NS_FAILED(rv)) {
+ DoError();
+ }
+ return rv;
+}
+
+nsresult RasterImage::SetSourceSizeHint(uint32_t aSizeHint) {
+ if (aSizeHint == 0) {
+ return NS_OK;
+ }
+
+ nsresult rv = mSourceBuffer->ExpectLength(aSizeHint);
+ if (rv == NS_ERROR_OUT_OF_MEMORY) {
+ // Flush memory, try to get some back, and try again.
+ rv = nsMemory::HeapMinimize(true);
+ if (NS_SUCCEEDED(rv)) {
+ rv = mSourceBuffer->ExpectLength(aSizeHint);
+ }
+ }
+
+ return rv;
+}
+
+nsresult RasterImage::GetHotspotX(int32_t* aX) {
+ *aX = mHotspot.x;
+ return NS_OK;
+}
+
+nsresult RasterImage::GetHotspotY(int32_t* aY) {
+ *aY = mHotspot.y;
+ return NS_OK;
+}
+
+void RasterImage::Discard() {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(CanDiscard(), "Asked to discard but can't");
+ MOZ_ASSERT(!mAnimationState ||
+ StaticPrefs::image_mem_animated_discardable_AtStartup(),
+ "Asked to discard for animated image");
+
+ // Delete all the decoded frames.
+ SurfaceCache::RemoveImage(ImageKey(this));
+
+ if (mAnimationState) {
+ IntRect rect = mAnimationState->UpdateState(this, mSize.ToUnknownSize());
+
+ auto dirtyRect = OrientedIntRect::FromUnknownRect(rect);
+ NotifyProgress(NoProgress, dirtyRect);
+ }
+
+ // Notify that we discarded.
+ if (mProgressTracker) {
+ mProgressTracker->OnDiscard();
+ }
+}
+
+bool RasterImage::CanDiscard() {
+ return LoadAllSourceData() &&
+ // Can discard animated images if the pref is set
+ (!mAnimationState ||
+ StaticPrefs::image_mem_animated_discardable_AtStartup());
+}
+
+NS_IMETHODIMP
+RasterImage::StartDecoding(uint32_t aFlags, uint32_t aWhichFrame) {
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (!LoadHasSize()) {
+ StoreWantFullDecode(true);
+ return NS_OK;
+ }
+
+ uint32_t flags = (aFlags & FLAG_ASYNC_NOTIFY) | FLAG_SYNC_DECODE_IF_FAST |
+ FLAG_HIGH_QUALITY_SCALING;
+ return RequestDecodeForSize(mSize.ToUnknownSize(), flags, aWhichFrame);
+}
+
+bool RasterImage::StartDecodingWithResult(uint32_t aFlags,
+ uint32_t aWhichFrame) {
+ if (mError) {
+ return false;
+ }
+
+ if (!LoadHasSize()) {
+ StoreWantFullDecode(true);
+ return false;
+ }
+
+ uint32_t flags = (aFlags & FLAG_ASYNC_NOTIFY) | FLAG_SYNC_DECODE_IF_FAST |
+ FLAG_HIGH_QUALITY_SCALING;
+ LookupResult result = RequestDecodeForSizeInternal(mSize, flags, aWhichFrame);
+ DrawableSurface surface = std::move(result.Surface());
+ return surface && surface->IsFinished();
+}
+
+bool RasterImage::HasDecodedPixels() {
+ LookupResult result = SurfaceCache::LookupBestMatch(
+ ImageKey(this),
+ RasterSurfaceKey(mSize.ToUnknownSize(), DefaultSurfaceFlags(),
+ PlaybackType::eStatic),
+ /* aMarkUsed = */ false);
+ MatchType matchType = result.Type();
+ if (matchType == MatchType::NOT_FOUND || matchType == MatchType::PENDING ||
+ !bool(result.Surface())) {
+ return false;
+ }
+
+ return !result.Surface()->GetDecodedRect().IsEmpty();
+}
+
+imgIContainer::DecodeResult RasterImage::RequestDecodeWithResult(
+ uint32_t aFlags, uint32_t aWhichFrame) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (mError) {
+ return imgIContainer::DECODE_REQUEST_FAILED;
+ }
+
+ uint32_t flags = aFlags | FLAG_ASYNC_NOTIFY;
+ LookupResult result = RequestDecodeForSizeInternal(mSize, flags, aWhichFrame);
+ DrawableSurface surface = std::move(result.Surface());
+ if (surface && surface->IsFinished()) {
+ return imgIContainer::DECODE_SURFACE_AVAILABLE;
+ }
+ if (result.GetFailedToRequestDecode()) {
+ return imgIContainer::DECODE_REQUEST_FAILED;
+ }
+ return imgIContainer::DECODE_REQUESTED;
+}
+
+NS_IMETHODIMP
+RasterImage::RequestDecodeForSize(const IntSize& aSize, uint32_t aFlags,
+ uint32_t aWhichFrame) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ RequestDecodeForSizeInternal(OrientedIntSize::FromUnknownSize(aSize), aFlags,
+ aWhichFrame);
+
+ return NS_OK;
+}
+
+LookupResult RasterImage::RequestDecodeForSizeInternal(
+ const OrientedIntSize& aSize, uint32_t aFlags, uint32_t aWhichFrame) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (aWhichFrame > FRAME_MAX_VALUE) {
+ return LookupResult(MatchType::NOT_FOUND);
+ }
+
+ if (mError) {
+ LookupResult result = LookupResult(MatchType::NOT_FOUND);
+ result.SetFailedToRequestDecode();
+ return result;
+ }
+
+ if (!LoadHasSize()) {
+ StoreWantFullDecode(true);
+ return LookupResult(MatchType::NOT_FOUND);
+ }
+
+ // Decide whether to sync decode images we can decode quickly. Here we are
+ // explicitly trading off flashing for responsiveness in the case that we're
+ // redecoding an image (see bug 845147).
+ bool shouldSyncDecodeIfFast =
+ !LoadHasBeenDecoded() && (aFlags & FLAG_SYNC_DECODE_IF_FAST);
+
+ uint32_t flags =
+ shouldSyncDecodeIfFast ? aFlags : aFlags & ~FLAG_SYNC_DECODE_IF_FAST;
+
+ // Perform a frame lookup, which will implicitly start decoding if needed.
+ return LookupFrame(aSize, flags, ToPlaybackType(aWhichFrame),
+ /* aMarkUsed = */ false);
+}
+
+static bool LaunchDecodingTask(IDecodingTask* aTask, RasterImage* aImage,
+ uint32_t aFlags, bool aHaveSourceData) {
+ if (aHaveSourceData) {
+ nsCString uri(aImage->GetURIString());
+
+ // If we have all the data, we can sync decode if requested.
+ if (aFlags & imgIContainer::FLAG_SYNC_DECODE) {
+ DecodePool::Singleton()->SyncRunIfPossible(aTask, uri);
+ return true;
+ }
+
+ if (aFlags & imgIContainer::FLAG_SYNC_DECODE_IF_FAST) {
+ return DecodePool::Singleton()->SyncRunIfPreferred(aTask, uri);
+ }
+ }
+
+ // Perform an async decode. We also take this path if we don't have all the
+ // source data yet, since sync decoding is impossible in that situation.
+ DecodePool::Singleton()->AsyncRun(aTask);
+ return false;
+}
+
+void RasterImage::Decode(const OrientedIntSize& aSize, uint32_t aFlags,
+ PlaybackType aPlaybackType, bool& aOutRanSync,
+ bool& aOutFailed) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (mError) {
+ aOutFailed = true;
+ return;
+ }
+
+ // If we don't have a size yet, we can't do any other decoding.
+ if (!LoadHasSize()) {
+ StoreWantFullDecode(true);
+ return;
+ }
+
+ // We're about to decode again, which may mean that some of the previous sizes
+ // we've decoded at aren't useful anymore. We can allow them to expire from
+ // the cache by unlocking them here. When the decode finishes, it will send an
+ // invalidation that will cause all instances of this image to redraw. If this
+ // image is locked, any surfaces that are still useful will become locked
+ // again when LookupFrame touches them, and the remainder will eventually
+ // expire.
+ SurfaceCache::UnlockEntries(ImageKey(this));
+
+ // Determine which flags we need to decode this image with.
+ DecoderFlags decoderFlags = mDefaultDecoderFlags;
+ if (aFlags & FLAG_ASYNC_NOTIFY) {
+ decoderFlags |= DecoderFlags::ASYNC_NOTIFY;
+ }
+ if (LoadTransient()) {
+ decoderFlags |= DecoderFlags::IMAGE_IS_TRANSIENT;
+ }
+ if (LoadHasBeenDecoded()) {
+ decoderFlags |= DecoderFlags::IS_REDECODE;
+ }
+ if ((aFlags & FLAG_SYNC_DECODE) || !(aFlags & FLAG_HIGH_QUALITY_SCALING)) {
+ // Used SurfaceCache::Lookup instead of SurfaceCache::LookupBestMatch. That
+ // means the caller can handle a differently sized surface to be returned
+ // at any point.
+ decoderFlags |= DecoderFlags::CANNOT_SUBSTITUTE;
+ }
+
+ SurfaceFlags surfaceFlags = ToSurfaceFlags(aFlags);
+ if (IsOpaque()) {
+ // If there's no transparency, it doesn't matter whether we premultiply
+ // alpha or not.
+ surfaceFlags &= ~SurfaceFlags::NO_PREMULTIPLY_ALPHA;
+ }
+
+ // Create a decoder.
+ RefPtr<IDecodingTask> task;
+ nsresult rv;
+ bool animated = mAnimationState && aPlaybackType == PlaybackType::eAnimated;
+ if (animated) {
+ size_t currentFrame = mAnimationState->GetCurrentAnimationFrameIndex();
+ rv = DecoderFactory::CreateAnimationDecoder(
+ mDecoderType, WrapNotNull(this), mSourceBuffer, mSize.ToUnknownSize(),
+ decoderFlags, surfaceFlags, currentFrame, getter_AddRefs(task));
+ } else {
+ rv = DecoderFactory::CreateDecoder(mDecoderType, WrapNotNull(this),
+ mSourceBuffer, mSize.ToUnknownSize(),
+ aSize.ToUnknownSize(), decoderFlags,
+ surfaceFlags, getter_AddRefs(task));
+ }
+
+ if (rv == NS_ERROR_ALREADY_INITIALIZED) {
+ // We raced with an already pending decoder, and it finished before we
+ // managed to insert the new decoder. Pretend we did a sync call to make
+ // the caller lookup in the surface cache again.
+ MOZ_ASSERT(!task);
+ aOutRanSync = true;
+ return;
+ }
+
+ if (animated) {
+ // We pass false for aAllowInvalidation because we may be asked to use
+ // async notifications. Any potential invalidation here will be sent when
+ // RequestRefresh is called, or NotifyDecodeComplete.
+#ifdef DEBUG
+ IntRect rect =
+#endif
+ mAnimationState->UpdateState(this, mSize.ToUnknownSize(), false);
+ MOZ_ASSERT(rect.IsEmpty());
+ }
+
+ // Make sure DecoderFactory was able to create a decoder successfully.
+ if (NS_FAILED(rv)) {
+ MOZ_ASSERT(!task);
+ aOutFailed = true;
+ return;
+ }
+
+ MOZ_ASSERT(task);
+ mDecodeCount++;
+
+ // We're ready to decode; start the decoder.
+ aOutRanSync = LaunchDecodingTask(task, this, aFlags, LoadAllSourceData());
+}
+
+NS_IMETHODIMP
+RasterImage::DecodeMetadata(uint32_t aFlags) {
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ MOZ_ASSERT(!LoadHasSize(), "Should not do unnecessary metadata decodes");
+
+ // Create a decoder.
+ RefPtr<IDecodingTask> task = DecoderFactory::CreateMetadataDecoder(
+ mDecoderType, WrapNotNull(this), mDefaultDecoderFlags, mSourceBuffer);
+
+ // Make sure DecoderFactory was able to create a decoder successfully.
+ if (!task) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // We're ready to decode; start the decoder.
+ LaunchDecodingTask(task, this, aFlags, LoadAllSourceData());
+ return NS_OK;
+}
+
+void RasterImage::RecoverFromInvalidFrames(const OrientedIntSize& aSize,
+ uint32_t aFlags) {
+ if (!LoadHasSize()) {
+ return;
+ }
+
+ NS_WARNING("A RasterImage's frames became invalid. Attempting to recover...");
+
+ // Discard all existing frames, since they're probably all now invalid.
+ SurfaceCache::RemoveImage(ImageKey(this));
+
+ // Relock the image if it's supposed to be locked.
+ if (mLockCount > 0) {
+ SurfaceCache::LockImage(ImageKey(this));
+ }
+
+ bool unused1, unused2;
+
+ // Animated images require some special handling, because we normally require
+ // that they never be discarded.
+ if (mAnimationState) {
+ Decode(mSize, aFlags | FLAG_SYNC_DECODE, PlaybackType::eAnimated, unused1,
+ unused2);
+ ResetAnimation();
+ return;
+ }
+
+ // For non-animated images, it's fine to recover using an async decode.
+ Decode(aSize, aFlags, PlaybackType::eStatic, unused1, unused2);
+}
+
+bool RasterImage::CanDownscaleDuringDecode(const OrientedIntSize& aSize,
+ uint32_t aFlags) {
+ // Check basic requirements: downscale-during-decode is enabled, Skia is
+ // available, this image isn't transient, we have all the source data and know
+ // our size, and the flags allow us to do it.
+ if (!LoadHasSize() || LoadTransient() ||
+ !StaticPrefs::image_downscale_during_decode_enabled() ||
+ !(aFlags & imgIContainer::FLAG_HIGH_QUALITY_SCALING)) {
+ return false;
+ }
+
+ // We don't downscale animated images during decode.
+ if (mAnimationState) {
+ return false;
+ }
+
+ // Never upscale.
+ if (aSize.width >= mSize.width || aSize.height >= mSize.height) {
+ return false;
+ }
+
+ // Zero or negative width or height is unacceptable.
+ if (aSize.width < 1 || aSize.height < 1) {
+ return false;
+ }
+
+ // There's no point in scaling if we can't store the result.
+ if (!SurfaceCache::CanHold(aSize.ToUnknownSize())) {
+ return false;
+ }
+
+ return true;
+}
+
+ImgDrawResult RasterImage::DrawInternal(DrawableSurface&& aSurface,
+ gfxContext* aContext,
+ const OrientedIntSize& aSize,
+ const ImageRegion& aRegion,
+ SamplingFilter aSamplingFilter,
+ uint32_t aFlags, float aOpacity) {
+ gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
+ ImageRegion region(aRegion);
+ bool frameIsFinished = aSurface->IsFinished();
+
+ AutoProfilerImagePaintMarker PROFILER_RAII(this);
+#ifdef DEBUG
+ NotifyDrawingObservers();
+#endif
+
+ // By now we may have a frame with the requested size. If not, we need to
+ // adjust the drawing parameters accordingly.
+ IntSize finalSize = aSurface->GetSize();
+ bool couldRedecodeForBetterFrame = false;
+ if (finalSize != aSize.ToUnknownSize()) {
+ gfx::MatrixScales scale(double(aSize.width) / finalSize.width,
+ double(aSize.height) / finalSize.height);
+ aContext->Multiply(gfx::Matrix::Scaling(scale));
+ region.Scale(1.0 / scale.xScale, 1.0 / scale.yScale);
+
+ couldRedecodeForBetterFrame = CanDownscaleDuringDecode(aSize, aFlags);
+ }
+
+ if (!aSurface->Draw(aContext, region, aSamplingFilter, aFlags, aOpacity)) {
+ RecoverFromInvalidFrames(aSize, aFlags);
+ return ImgDrawResult::TEMPORARY_ERROR;
+ }
+ if (!frameIsFinished) {
+ return ImgDrawResult::INCOMPLETE;
+ }
+ if (couldRedecodeForBetterFrame) {
+ return ImgDrawResult::WRONG_SIZE;
+ }
+ return ImgDrawResult::SUCCESS;
+}
+
+//******************************************************************************
+NS_IMETHODIMP_(ImgDrawResult)
+RasterImage::Draw(gfxContext* aContext, const IntSize& aSize,
+ const ImageRegion& aRegion, uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ const SVGImageContext& /*aSVGContext - ignored*/,
+ uint32_t aFlags, float aOpacity) {
+ if (aWhichFrame > FRAME_MAX_VALUE) {
+ return ImgDrawResult::BAD_ARGS;
+ }
+
+ if (mError) {
+ return ImgDrawResult::BAD_IMAGE;
+ }
+
+ // Illegal -- you can't draw with non-default decode flags.
+ // (Disabling colorspace conversion might make sense to allow, but
+ // we don't currently.)
+ if (ToSurfaceFlags(aFlags) != DefaultSurfaceFlags()) {
+ return ImgDrawResult::BAD_ARGS;
+ }
+
+ if (!aContext) {
+ return ImgDrawResult::BAD_ARGS;
+ }
+
+ if (mAnimationConsumers == 0 && mAnimationState) {
+ SendOnUnlockedDraw(aFlags);
+ }
+
+ // If we're not using SamplingFilter::GOOD, we shouldn't high-quality scale or
+ // downscale during decode.
+ uint32_t flags = aSamplingFilter == SamplingFilter::GOOD
+ ? aFlags
+ : aFlags & ~FLAG_HIGH_QUALITY_SCALING;
+
+ auto size = OrientedIntSize::FromUnknownSize(aSize);
+ LookupResult result = LookupFrame(size, flags, ToPlaybackType(aWhichFrame),
+ /* aMarkUsed = */ true);
+ if (!result) {
+ // Getting the frame (above) touches the image and kicks off decoding.
+ if (mDrawStartTime.IsNull()) {
+ mDrawStartTime = TimeStamp::Now();
+ }
+ return ImgDrawResult::NOT_READY;
+ }
+
+ bool shouldRecordTelemetry =
+ !mDrawStartTime.IsNull() && result.Surface()->IsFinished();
+
+ ImgDrawResult drawResult =
+ DrawInternal(std::move(result.Surface()), aContext, size, aRegion,
+ aSamplingFilter, flags, aOpacity);
+
+ if (shouldRecordTelemetry) {
+ TimeDuration drawLatency = TimeStamp::Now() - mDrawStartTime;
+ Telemetry::Accumulate(Telemetry::IMAGE_DECODE_ON_DRAW_LATENCY,
+ int32_t(drawLatency.ToMicroseconds()));
+ mDrawStartTime = TimeStamp();
+ }
+
+ return drawResult;
+}
+
+//******************************************************************************
+
+NS_IMETHODIMP
+RasterImage::LockImage() {
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Main thread to encourage serialization with UnlockImage");
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Increment the lock count
+ mLockCount++;
+
+ // Lock this image's surfaces in the SurfaceCache.
+ if (mLockCount == 1) {
+ SurfaceCache::LockImage(ImageKey(this));
+ }
+
+ return NS_OK;
+}
+
+//******************************************************************************
+
+NS_IMETHODIMP
+RasterImage::UnlockImage() {
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Main thread to encourage serialization with LockImage");
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // It's an error to call this function if the lock count is 0
+ MOZ_ASSERT(mLockCount > 0, "Calling UnlockImage with mLockCount == 0!");
+ if (mLockCount == 0) {
+ return NS_ERROR_ABORT;
+ }
+
+ // Decrement our lock count
+ mLockCount--;
+
+ // Unlock this image's surfaces in the SurfaceCache.
+ if (mLockCount == 0) {
+ SurfaceCache::UnlockImage(ImageKey(this));
+ }
+
+ return NS_OK;
+}
+
+//******************************************************************************
+
+NS_IMETHODIMP
+RasterImage::RequestDiscard() {
+ if (LoadDiscardable() && // Enabled at creation time...
+ mLockCount == 0 && // ...not temporarily disabled...
+ CanDiscard()) {
+ Discard();
+ }
+
+ return NS_OK;
+}
+
+// Idempotent error flagging routine. If a decoder is open, shuts it down.
+void RasterImage::DoError() {
+ // If we've flagged an error before, we have nothing to do
+ if (mError) {
+ return;
+ }
+
+ // We can't safely handle errors off-main-thread, so dispatch a worker to
+ // do it.
+ if (!NS_IsMainThread()) {
+ HandleErrorWorker::DispatchIfNeeded(this);
+ return;
+ }
+
+ // Put the container in an error state.
+ mError = true;
+
+ // Stop animation and release our FrameAnimator.
+ if (mAnimating) {
+ StopAnimation();
+ }
+ mAnimationState = Nothing();
+ mFrameAnimator = nullptr;
+
+ // Release all locks.
+ mLockCount = 0;
+ SurfaceCache::UnlockImage(ImageKey(this));
+
+ // Release all frames from the surface cache.
+ SurfaceCache::RemoveImage(ImageKey(this));
+
+ // Invalidate to get rid of any partially-drawn image content.
+ auto dirtyRect = OrientedIntRect({0, 0}, mSize);
+ NotifyProgress(NoProgress, dirtyRect);
+
+ MOZ_LOG(gImgLog, LogLevel::Error,
+ ("RasterImage: [this=%p] Error detected for image\n", this));
+}
+
+/* static */
+void RasterImage::HandleErrorWorker::DispatchIfNeeded(RasterImage* aImage) {
+ RefPtr<HandleErrorWorker> worker = new HandleErrorWorker(aImage);
+ NS_DispatchToMainThread(worker);
+}
+
+RasterImage::HandleErrorWorker::HandleErrorWorker(RasterImage* aImage)
+ : Runnable("image::RasterImage::HandleErrorWorker"), mImage(aImage) {
+ MOZ_ASSERT(mImage, "Should have image");
+}
+
+NS_IMETHODIMP
+RasterImage::HandleErrorWorker::Run() {
+ mImage->DoError();
+
+ return NS_OK;
+}
+
+bool RasterImage::ShouldAnimate() {
+ return ImageResource::ShouldAnimate() && mAnimationState &&
+ mAnimationState->KnownFrameCount() >= 1 && !LoadAnimationFinished();
+}
+
+#ifdef DEBUG
+NS_IMETHODIMP
+RasterImage::GetFramesNotified(uint32_t* aFramesNotified) {
+ NS_ENSURE_ARG_POINTER(aFramesNotified);
+
+ *aFramesNotified = mFramesNotified;
+
+ return NS_OK;
+}
+#endif
+
+void RasterImage::NotifyProgress(
+ Progress aProgress,
+ const OrientedIntRect& aInvalidRect /* = OrientedIntRect() */,
+ const Maybe<uint32_t>& aFrameCount /* = Nothing() */,
+ DecoderFlags aDecoderFlags /* = DefaultDecoderFlags() */,
+ SurfaceFlags aSurfaceFlags /* = DefaultSurfaceFlags() */) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ // Ensure that we stay alive long enough to finish notifying.
+ RefPtr<RasterImage> image = this;
+
+ OrientedIntRect invalidRect = aInvalidRect;
+
+ if (!(aDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY)) {
+ // We may have decoded new animation frames; update our animation state.
+ MOZ_ASSERT_IF(aFrameCount && *aFrameCount > 1, mAnimationState || mError);
+ if (mAnimationState && aFrameCount) {
+ mAnimationState->UpdateKnownFrameCount(*aFrameCount);
+ }
+
+ // If we should start animating right now, do so.
+ if (mAnimationState && aFrameCount == Some(1u) && LoadPendingAnimation() &&
+ ShouldAnimate()) {
+ StartAnimation();
+ }
+
+ if (mAnimationState) {
+ IntRect rect = mAnimationState->UpdateState(this, mSize.ToUnknownSize());
+
+ invalidRect.UnionRect(invalidRect,
+ OrientedIntRect::FromUnknownRect(rect));
+ }
+ }
+
+ // Tell the observers what happened.
+ image->mProgressTracker->SyncNotifyProgress(aProgress,
+ invalidRect.ToUnknownRect());
+}
+
+void RasterImage::NotifyDecodeComplete(
+ const DecoderFinalStatus& aStatus, const ImageMetadata& aMetadata,
+ const DecoderTelemetry& aTelemetry, Progress aProgress,
+ const OrientedIntRect& aInvalidRect, const Maybe<uint32_t>& aFrameCount,
+ DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ // If the decoder detected an error, log it to the error console.
+ if (aStatus.mShouldReportError) {
+ ReportDecoderError();
+ }
+
+ // Record all the metadata the decoder gathered about this image.
+ bool metadataOK = SetMetadata(aMetadata, aStatus.mWasMetadataDecode);
+ if (!metadataOK) {
+ // This indicates a serious error that requires us to discard all existing
+ // surfaces and redecode to recover. We'll drop the results from this
+ // decoder on the floor, since they aren't valid.
+ RecoverFromInvalidFrames(mSize, FromSurfaceFlags(aSurfaceFlags));
+ return;
+ }
+
+ MOZ_ASSERT(mError || LoadHasSize() || !aMetadata.HasSize(),
+ "SetMetadata should've gotten a size");
+
+ if (!aStatus.mWasMetadataDecode && aStatus.mFinished) {
+ // Flag that we've been decoded before.
+ StoreHasBeenDecoded(true);
+ }
+
+ // Send out any final notifications.
+ NotifyProgress(aProgress, aInvalidRect, aFrameCount, aDecoderFlags,
+ aSurfaceFlags);
+
+ if (!(aDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY)) {
+ // We may have decoded new animation frames; update our animation state.
+ MOZ_ASSERT_IF(aFrameCount && *aFrameCount > 1, mAnimationState || mError);
+ if (mAnimationState && aFrameCount) {
+ mAnimationState->UpdateKnownFrameCount(*aFrameCount);
+ }
+
+ // If we should start animating right now, do so.
+ if (mAnimationState && aFrameCount == Some(1u) && LoadPendingAnimation() &&
+ ShouldAnimate()) {
+ StartAnimation();
+ }
+
+ if (mAnimationState && LoadHasBeenDecoded()) {
+ // We've finished a full decode of all animation frames and our
+ // AnimationState has been notified about them all, so let it know not to
+ // expect anymore.
+ mAnimationState->NotifyDecodeComplete();
+
+ IntRect rect = mAnimationState->UpdateState(this, mSize.ToUnknownSize());
+
+ if (!rect.IsEmpty()) {
+ auto dirtyRect = OrientedIntRect::FromUnknownRect(rect);
+ NotifyProgress(NoProgress, dirtyRect);
+ }
+ }
+ }
+
+ // Do some telemetry if this isn't a metadata decode.
+ if (!aStatus.mWasMetadataDecode) {
+ if (aTelemetry.mChunkCount) {
+ Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS,
+ aTelemetry.mChunkCount);
+ }
+
+ if (aStatus.mFinished) {
+ Telemetry::Accumulate(Telemetry::IMAGE_DECODE_TIME,
+ int32_t(aTelemetry.mDecodeTime.ToMicroseconds()));
+
+ if (aTelemetry.mSpeedHistogram && aTelemetry.mBytesDecoded) {
+ Telemetry::Accumulate(*aTelemetry.mSpeedHistogram, aTelemetry.Speed());
+ }
+ }
+ }
+
+ // Only act on errors if we have no usable frames from the decoder.
+ if (aStatus.mHadError &&
+ (!mAnimationState || mAnimationState->KnownFrameCount() == 0)) {
+ DoError();
+ } else if (aStatus.mWasMetadataDecode && !LoadHasSize()) {
+ DoError();
+ }
+
+ // XXX(aosmond): Can we get this far without mFinished == true?
+ if (aStatus.mFinished && aStatus.mWasMetadataDecode) {
+ // If we were waiting to fire the load event, go ahead and fire it now.
+ if (mLoadProgress) {
+ NotifyForLoadEvent(*mLoadProgress);
+ mLoadProgress = Nothing();
+ }
+
+ // If we were a metadata decode and a full decode was requested, do it.
+ if (LoadWantFullDecode()) {
+ StoreWantFullDecode(false);
+ RequestDecodeForSizeInternal(mSize,
+ DECODE_FLAGS_DEFAULT |
+ FLAG_HIGH_QUALITY_SCALING |
+ FLAG_AVOID_REDECODE_FOR_SIZE,
+ FRAME_CURRENT);
+ }
+ }
+}
+
+void RasterImage::ReportDecoderError() {
+ nsCOMPtr<nsIConsoleService> consoleService =
+ do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+ nsCOMPtr<nsIScriptError> errorObject =
+ do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
+
+ if (consoleService && errorObject) {
+ nsAutoString msg(u"Image corrupt or truncated."_ns);
+ nsAutoString src;
+ if (GetURI()) {
+ nsAutoCString uri;
+ if (!GetSpecTruncatedTo1k(uri)) {
+ msg += u" URI in this note truncated due to length."_ns;
+ }
+ CopyUTF8toUTF16(uri, src);
+ }
+ if (NS_SUCCEEDED(errorObject->InitWithWindowID(msg, src, u""_ns, 0, 0,
+ nsIScriptError::errorFlag,
+ "Image", InnerWindowID()))) {
+ consoleService->LogMessage(errorObject);
+ }
+ }
+}
+
+already_AddRefed<imgIContainer> RasterImage::Unwrap() {
+ nsCOMPtr<imgIContainer> self(this);
+ return self.forget();
+}
+
+void RasterImage::PropagateUseCounters(dom::Document*) {
+ // No use counters.
+}
+
+IntSize RasterImage::OptimalImageSizeForDest(const gfxSize& aDest,
+ uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ uint32_t aFlags) {
+ MOZ_ASSERT(aDest.width >= 0 || ceil(aDest.width) <= INT32_MAX ||
+ aDest.height >= 0 || ceil(aDest.height) <= INT32_MAX,
+ "Unexpected destination size");
+
+ if (mSize.IsEmpty() || aDest.IsEmpty()) {
+ return IntSize(0, 0);
+ }
+
+ auto dest = OrientedIntSize::FromUnknownSize(
+ IntSize::Ceil(aDest.width, aDest.height));
+
+ if (aSamplingFilter == SamplingFilter::GOOD &&
+ CanDownscaleDuringDecode(dest, aFlags)) {
+ return dest.ToUnknownSize();
+ }
+
+ // We can't scale to this size. Use our intrinsic size for now.
+ return mSize.ToUnknownSize();
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/RasterImage.h b/image/RasterImage.h
new file mode 100644
index 0000000000..28cc56e54e
--- /dev/null
+++ b/image/RasterImage.h
@@ -0,0 +1,484 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/** @file
+ * This file declares the RasterImage class, which
+ * handles static and animated rasterized images.
+ *
+ * @author Stuart Parmenter <pavlov@netscape.com>
+ * @author Chris Saari <saari@netscape.com>
+ * @author Arron Mogge <paper@animecity.nu>
+ * @author Andrew Smith <asmith15@learn.senecac.on.ca>
+ */
+
+#ifndef mozilla_image_RasterImage_h
+#define mozilla_image_RasterImage_h
+
+#include "Image.h"
+#include "nsCOMPtr.h"
+#include "imgIContainer.h"
+#include "nsTArray.h"
+#include "LookupResult.h"
+#include "nsThreadUtils.h"
+#include "DecoderFactory.h"
+#include "FrameAnimator.h"
+#include "ImageMetadata.h"
+#include "ISurfaceProvider.h"
+#include "Orientation.h"
+#include "mozilla/AtomicBitfields.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/NotNull.h"
+#include "mozilla/StaticPrefs_image.h"
+#include "mozilla/TimeStamp.h"
+#include "mozilla/WeakPtr.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/image/Resolution.h"
+#include "ImageContainer.h"
+#include "PlaybackType.h"
+#ifdef DEBUG
+# include "imgIContainerDebug.h"
+#endif
+
+class nsIInputStream;
+class nsIRequest;
+
+#define NS_RASTERIMAGE_CID \
+ { /* 376ff2c1-9bf6-418a-b143-3340c00112f7 */ \
+ 0x376ff2c1, 0x9bf6, 0x418a, { \
+ 0xb1, 0x43, 0x33, 0x40, 0xc0, 0x01, 0x12, 0xf7 \
+ } \
+ }
+
+/**
+ * Handles static and animated image containers.
+ *
+ *
+ * @par A Quick Walk Through
+ * The decoder initializes this class and calls AppendFrame() to add a frame.
+ * Once RasterImage detects more than one frame, it starts the animation
+ * with StartAnimation(). Note that the invalidation events for RasterImage are
+ * generated automatically using nsRefreshDriver.
+ *
+ * @par
+ * StartAnimation() initializes the animation helper object and sets the time
+ * the first frame was displayed to the current clock time.
+ *
+ * @par
+ * When the refresh driver corresponding to the imgIContainer that this image is
+ * a part of notifies the RasterImage that it's time to invalidate,
+ * RequestRefresh() is called with a given TimeStamp to advance to. As long as
+ * the timeout of the given frame (the frame's "delay") plus the time that frame
+ * was first displayed is less than or equal to the TimeStamp given,
+ * RequestRefresh() calls AdvanceFrame().
+ *
+ * @par
+ * AdvanceFrame() is responsible for advancing a single frame of the animation.
+ * It can return true, meaning that the frame advanced, or false, meaning that
+ * the frame failed to advance (usually because the next frame hasn't been
+ * decoded yet). It is also responsible for performing the final animation stop
+ * procedure if the final frame of a non-looping animation is reached.
+ *
+ * @par
+ * Each frame can have a different method of removing itself. These are
+ * listed as imgIContainer::cDispose... constants. Notify() calls
+ * DoComposite() to handle any special frame destruction.
+ *
+ * @par
+ * The basic path through DoComposite() is:
+ * 1) Calculate Area that needs updating, which is at least the area of
+ * aNextFrame.
+ * 2) Dispose of previous frame.
+ * 3) Draw new image onto compositingFrame.
+ * See comments in DoComposite() for more information and optimizations.
+ *
+ * @par
+ * The rest of the RasterImage specific functions are used by DoComposite to
+ * destroy the old frame and build the new one.
+ *
+ * @note
+ * <li> "Mask", "Alpha", and "Alpha Level" are interchangeable phrases in
+ * respects to RasterImage.
+ *
+ * @par
+ * <li> GIFs never have more than a 1 bit alpha.
+ * <li> APNGs may have a full alpha channel.
+ *
+ * @par
+ * <li> Background color specified in GIF is ignored by web browsers.
+ *
+ * @par
+ * <li> If Frame 3 wants to dispose by restoring previous, what it wants is to
+ * restore the composition up to and including Frame 2, as well as Frame 2s
+ * disposal. So, in the middle of DoComposite when composing Frame 3, right
+ * after destroying Frame 2's area, we copy compositingFrame to
+ * prevCompositingFrame. When DoComposite gets called to do Frame 4, we
+ * copy prevCompositingFrame back, and then draw Frame 4 on top.
+ *
+ * @par
+ * The mAnim structure has members only needed for animated images, so
+ * it's not allocated until the second frame is added.
+ */
+
+namespace mozilla {
+namespace layers {
+class ImageContainer;
+class Image;
+class LayersManager;
+} // namespace layers
+
+namespace image {
+
+class Decoder;
+struct DecoderFinalStatus;
+struct DecoderTelemetry;
+class ImageMetadata;
+class SourceBuffer;
+
+class RasterImage final : public ImageResource,
+ public SupportsWeakPtr
+#ifdef DEBUG
+ ,
+ public imgIContainerDebug
+#endif
+{
+ // (no public constructor - use ImageFactory)
+ virtual ~RasterImage();
+
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_IMGICONTAINER
+#ifdef DEBUG
+ NS_DECL_IMGICONTAINERDEBUG
+#endif
+
+ virtual nsresult StartAnimation() override;
+ virtual nsresult StopAnimation() override;
+
+ // Methods inherited from Image
+ virtual void OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) override;
+
+ virtual size_t SizeOfSourceWithComputedFallback(
+ SizeOfState& aState) const override;
+
+ /* Triggers discarding. */
+ void Discard();
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Decoder callbacks.
+ //////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Sends the provided progress notifications to ProgressTracker.
+ *
+ * Main-thread only.
+ *
+ * @param aProgress The progress notifications to send.
+ * @param aInvalidRect An invalidation rect to send.
+ * @param aFrameCount If Some(), an updated count of the number of frames of
+ * animation the decoder has finished decoding so far.
+ * This is a lower bound for the total number of
+ * animation frames this image has.
+ * @param aDecoderFlags The decoder flags used by the decoder that generated
+ * these notifications, or DefaultDecoderFlags() if the
+ * notifications don't come from a decoder.
+ * @param aSurfaceFlags The surface flags used by the decoder that generated
+ * these notifications, or DefaultSurfaceFlags() if the
+ * notifications don't come from a decoder.
+ */
+ void NotifyProgress(Progress aProgress,
+ const OrientedIntRect& aInvalidRect = OrientedIntRect(),
+ const Maybe<uint32_t>& aFrameCount = Nothing(),
+ DecoderFlags aDecoderFlags = DefaultDecoderFlags(),
+ SurfaceFlags aSurfaceFlags = DefaultSurfaceFlags());
+
+ /**
+ * Records decoding results, sends out any final notifications, updates the
+ * state of this image, and records telemetry.
+ *
+ * Main-thread only.
+ *
+ * @param aStatus Final status information about the decoder. (Whether
+ * it encountered an error, etc.)
+ * @param aMetadata Metadata about this image that the decoder gathered.
+ * @param aTelemetry Telemetry data about the decoder.
+ * @param aProgress Any final progress notifications to send.
+ * @param aInvalidRect Any final invalidation rect to send.
+ * @param aFrameCount If Some(), a final updated count of the number of
+ * frames of animation the decoder has finished decoding so far. This is a
+ * lower bound for the total number of animation frames this image has.
+ * @param aDecoderFlags The decoder flags used by the decoder.
+ * @param aSurfaceFlags The surface flags used by the decoder.
+ */
+ void NotifyDecodeComplete(
+ const DecoderFinalStatus& aStatus, const ImageMetadata& aMetadata,
+ const DecoderTelemetry& aTelemetry, Progress aProgress,
+ const OrientedIntRect& aInvalidRect, const Maybe<uint32_t>& aFrameCount,
+ DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags);
+
+ // Helper method for NotifyDecodeComplete.
+ void ReportDecoderError();
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Network callbacks.
+ //////////////////////////////////////////////////////////////////////////////
+
+ virtual nsresult OnImageDataAvailable(nsIRequest* aRequest,
+ nsIInputStream* aInStr,
+ uint64_t aSourceOffset,
+ uint32_t aCount) override;
+ virtual nsresult OnImageDataComplete(nsIRequest* aRequest, nsresult aStatus,
+ bool aLastPart) override;
+
+ void NotifyForLoadEvent(Progress aProgress);
+
+ /**
+ * A hint of the number of bytes of source data that the image contains. If
+ * called early on, this can help reduce copying and reallocations by
+ * appropriately preallocating the source data buffer.
+ *
+ * We take this approach rather than having the source data management code do
+ * something more complicated (like chunklisting) because HTTP is by far the
+ * dominant source of images, and the Content-Length header is quite reliable.
+ * Thus, pre-allocation simplifies code and reduces the total number of
+ * allocations.
+ */
+ nsresult SetSourceSizeHint(uint32_t aSizeHint);
+
+ nsCString GetURIString() {
+ nsCString spec;
+ if (GetURI()) {
+ GetURI()->GetSpec(spec);
+ }
+ return spec;
+ }
+
+ private:
+ nsresult Init(const char* aMimeType, uint32_t aFlags);
+
+ /**
+ * Tries to retrieve a surface for this image with size @aSize, surface flags
+ * matching @aFlags, and a playback type of @aPlaybackType.
+ *
+ * If @aFlags specifies FLAG_SYNC_DECODE and we already have all the image
+ * data, we'll attempt a sync decode if no matching surface is found. If
+ * FLAG_SYNC_DECODE was not specified and no matching surface was found, we'll
+ * kick off an async decode so that the surface is (hopefully) available next
+ * time it's requested. aMarkUsed determines if we mark the surface used in
+ * the surface cache or not.
+ *
+ * @return a drawable surface, which may be empty if the requested surface
+ * could not be found.
+ */
+ LookupResult LookupFrame(const OrientedIntSize& aSize, uint32_t aFlags,
+ PlaybackType aPlaybackType, bool aMarkUsed);
+
+ /// Helper method for LookupFrame().
+ LookupResult LookupFrameInternal(const OrientedIntSize& aSize,
+ uint32_t aFlags, PlaybackType aPlaybackType,
+ bool aMarkUsed);
+
+ ImgDrawResult DrawInternal(DrawableSurface&& aFrameRef, gfxContext* aContext,
+ const OrientedIntSize& aSize,
+ const ImageRegion& aRegion,
+ gfx::SamplingFilter aSamplingFilter,
+ uint32_t aFlags, float aOpacity);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Decoding.
+ //////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Creates and runs a decoder, either synchronously or asynchronously
+ * according to @aFlags. Decodes at the provided target size @aSize, using
+ * decode flags @aFlags. Performs a single-frame decode of this image unless
+ * we know the image is animated *and* @aPlaybackType is
+ * PlaybackType::eAnimated.
+ *
+ * It's an error to call Decode() before this image's intrinsic size is
+ * available. A metadata decode must successfully complete first.
+ *
+ * aOutRanSync is set to true if the decode was run synchronously.
+ * aOutFailed is set to true if failed to start a decode.
+ */
+ void Decode(const OrientedIntSize& aSize, uint32_t aFlags,
+ PlaybackType aPlaybackType, bool& aOutRanSync, bool& aOutFailed);
+
+ /**
+ * Creates and runs a metadata decoder, either synchronously or
+ * asynchronously according to @aFlags.
+ */
+ NS_IMETHOD DecodeMetadata(uint32_t aFlags);
+
+ /**
+ * Sets the size, inherent orientation, animation metadata, and other
+ * information about the image gathered during decoding.
+ *
+ * This function may be called multiple times, but will throw an error if
+ * subsequent calls do not match the first.
+ *
+ * @param aMetadata The metadata to set on this image.
+ * @param aFromMetadataDecode True if this metadata came from a metadata
+ * decode; false if it came from a full decode.
+ * @return |true| unless a catastrophic failure was discovered. If |false| is
+ * returned, it indicates that the image is corrupt in a way that requires all
+ * surfaces to be discarded to recover.
+ */
+ bool SetMetadata(const ImageMetadata& aMetadata, bool aFromMetadataDecode);
+
+ /**
+ * In catastrophic circumstances like a GPU driver crash, the contents of our
+ * frames may become invalid. If the information we gathered during the
+ * metadata decode proves to be wrong due to image corruption, the frames we
+ * have may violate this class's invariants. Either way, we need to
+ * immediately discard the invalid frames and redecode so that callers don't
+ * perceive that we've entered an invalid state.
+ *
+ * RecoverFromInvalidFrames discards all existing frames and redecodes using
+ * the provided @aSize and @aFlags.
+ */
+ void RecoverFromInvalidFrames(const OrientedIntSize& aSize, uint32_t aFlags);
+
+ void OnSurfaceDiscardedInternal(bool aAnimatedFramesDiscarded);
+
+ private: // data
+ OrientedIntSize mSize;
+ nsTArray<OrientedIntSize> mNativeSizes;
+
+ // The orientation required to correctly orient the image, from the image's
+ // metadata. RasterImage will handle and apply this orientation itself.
+ Orientation mOrientation;
+
+ // The resolution as specified in the image metadata, in dppx.
+ Resolution mResolution;
+
+ /// If this has a value, we're waiting for SetSize() to send the load event.
+ Maybe<Progress> mLoadProgress;
+
+ // Hotspot of this image, or (0, 0) if there is no hotspot data.
+ //
+ // We assume (and assert) that no image has both orientation metadata and a
+ // hotspot, so we store this as an untyped point.
+ gfx::IntPoint mHotspot;
+
+ /// If this image is animated, a FrameAnimator which manages its animation.
+ UniquePtr<FrameAnimator> mFrameAnimator;
+
+ /// Animation timeline and other state for animation images.
+ Maybe<AnimationState> mAnimationState;
+
+ // Image locking.
+ uint32_t mLockCount;
+
+ // The type of decoder this image needs. Computed from the MIME type in
+ // Init().
+ DecoderType mDecoderType;
+
+ // How many times we've decoded this image.
+ // This is currently only used for statistics
+ int32_t mDecodeCount;
+
+#ifdef DEBUG
+ uint32_t mFramesNotified;
+#endif
+
+ // The source data for this image.
+ NotNull<RefPtr<SourceBuffer>> mSourceBuffer;
+
+ // Boolean flags (clustered together to conserve space):
+ MOZ_ATOMIC_BITFIELDS(
+ mAtomicBitfields, 16,
+ ((bool, HasSize, 1), // Has SetSize() been called?
+ (bool, Transient, 1), // Is the image short-lived?
+ (bool, SyncLoad, 1), // Are we loading synchronously?
+ (bool, Discardable, 1), // Is container discardable?
+ (bool, SomeSourceData, 1), // Do we have some source data?
+ (bool, AllSourceData, 1), // Do we have all the source data?
+ (bool, HasBeenDecoded, 1), // Decoded at least once?
+
+ // Whether we're waiting to start animation. If we get a StartAnimation()
+ // call but we don't yet have more than one frame, mPendingAnimation is
+ // set so that we know to start animation later if/when we have more
+ // frames.
+ (bool, PendingAnimation, 1),
+
+ // Whether the animation can stop, due to running out
+ // of frames, or no more owning request
+ (bool, AnimationFinished, 1),
+
+ // Whether, once we are done doing a metadata decode, we should
+ // immediately kick off a full decode.
+ (bool, WantFullDecode, 1)))
+
+ TimeStamp mDrawStartTime;
+
+ // This field is set according to the DecoderType of this image once when
+ // initialized so that a decoder's flags can be set according to any
+ // preferences that affect its behavior in a way that would otherwise cause
+ // errors, such as enabling or disabling animation.
+ DecoderFlags mDefaultDecoderFlags = DefaultDecoderFlags();
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Scaling.
+ //////////////////////////////////////////////////////////////////////////////
+
+ // Determines whether we can downscale during decode with the given
+ // parameters.
+ bool CanDownscaleDuringDecode(const OrientedIntSize& aSize, uint32_t aFlags);
+
+ // Error handling.
+ void DoError();
+
+ class HandleErrorWorker : public Runnable {
+ public:
+ /**
+ * Called from decoder threads when DoError() is called, since errors can't
+ * be handled safely off-main-thread. Dispatches an event which reinvokes
+ * DoError on the main thread if there isn't one already pending.
+ */
+ static void DispatchIfNeeded(RasterImage* aImage);
+
+ NS_IMETHOD Run() override;
+
+ private:
+ explicit HandleErrorWorker(RasterImage* aImage);
+
+ RefPtr<RasterImage> mImage;
+ };
+
+ // Helpers
+ bool CanDiscard();
+
+ bool IsOpaque();
+
+ LookupResult RequestDecodeForSizeInternal(const OrientedIntSize& aSize,
+ uint32_t aFlags,
+ uint32_t aWhichFrame);
+
+ protected:
+ explicit RasterImage(nsIURI* aURI = nullptr);
+
+ bool ShouldAnimate() override;
+
+ friend class ImageFactory;
+};
+
+inline NS_IMETHODIMP RasterImage::GetAnimationMode(uint16_t* aAnimationMode) {
+ return GetAnimationModeInternal(aAnimationMode);
+}
+
+} // namespace image
+} // namespace mozilla
+
+/**
+ * Casting RasterImage to nsISupports is ambiguous. This method handles that.
+ */
+inline nsISupports* ToSupports(mozilla::image::RasterImage* p) {
+ return NS_ISUPPORTS_CAST(mozilla::image::ImageResource*, p);
+}
+
+#endif /* mozilla_image_RasterImage_h */
diff --git a/image/Resolution.h b/image/Resolution.h
new file mode 100644
index 0000000000..b305b867b2
--- /dev/null
+++ b/image/Resolution.h
@@ -0,0 +1,90 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_Resolution_h
+#define mozilla_image_Resolution_h
+
+#include "mozilla/Assertions.h"
+#include <cmath>
+
+namespace mozilla {
+namespace image {
+
+/**
+ * The resolution of an image, in dppx.
+ */
+struct Resolution {
+ Resolution() = default;
+ Resolution(float aX, float aY) : mX(aX), mY(aY) {
+ MOZ_ASSERT(mX != 0.0f);
+ MOZ_ASSERT(mY != 0.0f);
+ }
+
+ bool operator==(const Resolution& aOther) const {
+ return mX == aOther.mX && mY == aOther.mY;
+ }
+ bool operator!=(const Resolution& aOther) const { return !(*this == aOther); }
+
+ float mX = 1.0f;
+ float mY = 1.0f;
+
+ void ScaleBy(float aScale) {
+ if (MOZ_LIKELY(aScale != 0.0f)) {
+ mX *= aScale;
+ mY *= aScale;
+ }
+ }
+
+ void ApplyXTo(int32_t& aWidth) const {
+ if (mX != 1.0f) {
+ aWidth = std::round(float(aWidth) / mX);
+ }
+ }
+
+ void ApplyXTo(float& aWidth) const {
+ if (mX != 1.0f) {
+ aWidth /= mX;
+ }
+ }
+
+ void ApplyYTo(int32_t& aHeight) const {
+ if (mY != 1.0f) {
+ aHeight = std::round(float(aHeight) / mY);
+ }
+ }
+
+ void ApplyYTo(float& aHeight) const {
+ if (mY != 1.0f) {
+ aHeight /= mY;
+ }
+ }
+
+ void ApplyTo(int32_t& aWidth, int32_t& aHeight) const {
+ ApplyXTo(aWidth);
+ ApplyYTo(aHeight);
+ }
+
+ void ApplyTo(float& aWidth, float& aHeight) const {
+ ApplyXTo(aWidth);
+ ApplyYTo(aHeight);
+ }
+
+ void ApplyInverseTo(int32_t& aWidth, int32_t& aHeight) {
+ if (mX != 1.0f) {
+ aWidth = std::round(float(aWidth) * mX);
+ }
+ if (mY != 1.0f) {
+ aHeight = std::round(float(aHeight) * mY);
+ }
+ }
+};
+
+} // namespace image
+
+using ImageResolution = image::Resolution;
+
+} // namespace mozilla
+
+#endif
diff --git a/image/SVGDocumentWrapper.cpp b/image/SVGDocumentWrapper.cpp
new file mode 100644
index 0000000000..2c081afb9e
--- /dev/null
+++ b/image/SVGDocumentWrapper.cpp
@@ -0,0 +1,401 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SVGDocumentWrapper.h"
+
+#include "mozilla/PresShell.h"
+#include "mozilla/SMILAnimationController.h"
+#include "mozilla/SVGObserverUtils.h"
+#include "mozilla/dom/Animation.h"
+#include "mozilla/dom/Document.h"
+#include "mozilla/dom/DocumentTimeline.h"
+#include "mozilla/dom/Element.h"
+#include "mozilla/dom/ImageTracker.h"
+#include "mozilla/dom/SVGDocument.h"
+#include "mozilla/dom/SVGSVGElement.h"
+#include "nsICategoryManager.h"
+#include "nsIChannel.h"
+#include "nsIContentViewer.h"
+#include "nsIDocumentLoaderFactory.h"
+#include "nsIHttpChannel.h"
+#include "nsIObserverService.h"
+#include "nsIParser.h"
+#include "nsIRequest.h"
+#include "nsIStreamListener.h"
+#include "nsIXMLContentSink.h"
+#include "nsNetCID.h"
+#include "nsComponentManagerUtils.h"
+#include "nsServiceManagerUtils.h"
+#include "nsMimeTypes.h"
+#include "nsRefreshDriver.h"
+
+namespace mozilla {
+
+using namespace dom;
+using namespace gfx;
+
+namespace image {
+
+NS_IMPL_ISUPPORTS(SVGDocumentWrapper, nsIStreamListener, nsIRequestObserver,
+ nsIObserver, nsISupportsWeakReference)
+
+SVGDocumentWrapper::SVGDocumentWrapper()
+ : mIgnoreInvalidation(false),
+ mRegisteredForXPCOMShutdown(false),
+ mIsDrawing(false) {}
+
+SVGDocumentWrapper::~SVGDocumentWrapper() {
+ DestroyViewer();
+ if (mRegisteredForXPCOMShutdown) {
+ UnregisterForXPCOMShutdown();
+ }
+}
+
+void SVGDocumentWrapper::DestroyViewer() {
+ if (mViewer) {
+ mViewer->GetDocument()->OnPageHide(false, nullptr);
+ mViewer->Close(nullptr);
+ mViewer->Destroy();
+ mViewer = nullptr;
+ }
+}
+
+nsIFrame* SVGDocumentWrapper::GetRootLayoutFrame() {
+ Element* rootElem = GetRootSVGElem();
+ return rootElem ? rootElem->GetPrimaryFrame() : nullptr;
+}
+
+void SVGDocumentWrapper::UpdateViewportBounds(const nsIntSize& aViewportSize) {
+ MOZ_ASSERT(!mIgnoreInvalidation, "shouldn't be reentrant");
+ mIgnoreInvalidation = true;
+
+ nsIntRect currentBounds;
+ mViewer->GetBounds(currentBounds);
+
+ // If the bounds have changed, we need to do a layout flush.
+ if (currentBounds.Size() != aViewportSize) {
+ mViewer->SetBounds(IntRect(IntPoint(0, 0), aViewportSize));
+ FlushLayout();
+ }
+
+ mIgnoreInvalidation = false;
+}
+
+void SVGDocumentWrapper::FlushImageTransformInvalidation() {
+ MOZ_ASSERT(!mIgnoreInvalidation, "shouldn't be reentrant");
+
+ SVGSVGElement* svgElem = GetRootSVGElem();
+ if (!svgElem) {
+ return;
+ }
+
+ mIgnoreInvalidation = true;
+ svgElem->FlushImageTransformInvalidation();
+ FlushLayout();
+ mIgnoreInvalidation = false;
+}
+
+bool SVGDocumentWrapper::IsAnimated() {
+ // Can be called for animated images during shutdown, after we've
+ // already Observe()'d XPCOM shutdown and cleared out our mViewer pointer.
+ if (!mViewer) {
+ return false;
+ }
+
+ Document* doc = mViewer->GetDocument();
+ if (!doc) {
+ return false;
+ }
+ if (doc->Timeline()->HasAnimations()) {
+ // CSS animations (technically HasAnimations() also checks for CSS
+ // transitions and Web animations but since SVG-as-an-image doesn't run
+ // script they will never run in the document that we wrap).
+ return true;
+ }
+ if (doc->HasAnimationController() &&
+ doc->GetAnimationController()->HasRegisteredAnimations()) {
+ // SMIL animations
+ return true;
+ }
+ return false;
+}
+
+void SVGDocumentWrapper::StartAnimation() {
+ // Can be called for animated images during shutdown, after we've
+ // already Observe()'d XPCOM shutdown and cleared out our mViewer pointer.
+ if (!mViewer) {
+ return;
+ }
+
+ Document* doc = mViewer->GetDocument();
+ if (doc) {
+ SMILAnimationController* controller = doc->GetAnimationController();
+ if (controller) {
+ controller->Resume(SMILTimeContainer::PAUSE_IMAGE);
+ }
+ doc->ImageTracker()->SetAnimatingState(true);
+ }
+}
+
+void SVGDocumentWrapper::StopAnimation() {
+ // Can be called for animated images during shutdown, after we've
+ // already Observe()'d XPCOM shutdown and cleared out our mViewer pointer.
+ if (!mViewer) {
+ return;
+ }
+
+ Document* doc = mViewer->GetDocument();
+ if (doc) {
+ SMILAnimationController* controller = doc->GetAnimationController();
+ if (controller) {
+ controller->Pause(SMILTimeContainer::PAUSE_IMAGE);
+ }
+ doc->ImageTracker()->SetAnimatingState(false);
+ }
+}
+
+void SVGDocumentWrapper::ResetAnimation() {
+ SVGSVGElement* svgElem = GetRootSVGElem();
+ if (!svgElem) {
+ return;
+ }
+
+ svgElem->SetCurrentTime(0.0f);
+}
+
+float SVGDocumentWrapper::GetCurrentTimeAsFloat() {
+ SVGSVGElement* svgElem = GetRootSVGElem();
+ return svgElem ? svgElem->GetCurrentTimeAsFloat() : 0.0f;
+}
+
+void SVGDocumentWrapper::SetCurrentTime(float aTime) {
+ SVGSVGElement* svgElem = GetRootSVGElem();
+ if (svgElem && svgElem->GetCurrentTimeAsFloat() != aTime) {
+ svgElem->SetCurrentTime(aTime);
+ }
+}
+
+void SVGDocumentWrapper::TickRefreshDriver() {
+ if (RefPtr<PresShell> presShell = mViewer->GetPresShell()) {
+ if (RefPtr<nsPresContext> presContext = presShell->GetPresContext()) {
+ if (RefPtr<nsRefreshDriver> driver = presContext->RefreshDriver()) {
+ driver->DoTick();
+ }
+ }
+ }
+}
+
+/** nsIStreamListener methods **/
+
+NS_IMETHODIMP
+SVGDocumentWrapper::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* inStr,
+ uint64_t sourceOffset, uint32_t count) {
+ return mListener->OnDataAvailable(aRequest, inStr, sourceOffset, count);
+}
+
+/** nsIRequestObserver methods **/
+
+NS_IMETHODIMP
+SVGDocumentWrapper::OnStartRequest(nsIRequest* aRequest) {
+ nsresult rv = SetupViewer(aRequest, getter_AddRefs(mViewer),
+ getter_AddRefs(mLoadGroup));
+
+ if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(mListener->OnStartRequest(aRequest))) {
+ mViewer->GetDocument()->SetIsBeingUsedAsImage();
+ StopAnimation(); // otherwise animations start automatically in helper doc
+
+ rv = mViewer->Init(nullptr, nsIntRect(0, 0, 0, 0), nullptr);
+ if (NS_SUCCEEDED(rv)) {
+ rv = mViewer->Open(nullptr, nullptr);
+ }
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+SVGDocumentWrapper::OnStopRequest(nsIRequest* aRequest, nsresult status) {
+ if (mListener) {
+ mListener->OnStopRequest(aRequest, status);
+ mListener = nullptr;
+ }
+
+ return NS_OK;
+}
+
+/** nsIObserver Methods **/
+NS_IMETHODIMP
+SVGDocumentWrapper::Observe(nsISupports* aSubject, const char* aTopic,
+ const char16_t* aData) {
+ if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
+ // Sever ties from rendering observers to helper-doc's root SVG node
+ SVGSVGElement* svgElem = GetRootSVGElem();
+ if (svgElem) {
+ SVGObserverUtils::RemoveAllRenderingObservers(svgElem);
+ }
+
+ // Clean up at XPCOM shutdown time.
+ DestroyViewer();
+ if (mListener) {
+ mListener = nullptr;
+ }
+ if (mLoadGroup) {
+ mLoadGroup = nullptr;
+ }
+
+ // Turn off "registered" flag, or else we'll try to unregister when we die.
+ // (No need for that now, and the try would fail anyway -- it's too late.)
+ mRegisteredForXPCOMShutdown = false;
+ } else {
+ NS_ERROR("Unexpected observer topic.");
+ }
+ return NS_OK;
+}
+
+/** Private helper methods **/
+
+// This method is largely cribbed from
+// nsExternalResourceMap::PendingLoad::SetupViewer.
+nsresult SVGDocumentWrapper::SetupViewer(nsIRequest* aRequest,
+ nsIContentViewer** aViewer,
+ nsILoadGroup** aLoadGroup) {
+ nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
+ NS_ENSURE_TRUE(chan, NS_ERROR_UNEXPECTED);
+
+ // Check for HTTP error page
+ nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequest));
+ if (httpChannel) {
+ bool requestSucceeded;
+ if (NS_FAILED(httpChannel->GetRequestSucceeded(&requestSucceeded)) ||
+ !requestSucceeded) {
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ // Give this document its own loadgroup
+ nsCOMPtr<nsILoadGroup> loadGroup;
+ chan->GetLoadGroup(getter_AddRefs(loadGroup));
+
+ nsCOMPtr<nsILoadGroup> newLoadGroup =
+ do_CreateInstance(NS_LOADGROUP_CONTRACTID);
+ NS_ENSURE_TRUE(newLoadGroup, NS_ERROR_OUT_OF_MEMORY);
+ newLoadGroup->SetLoadGroup(loadGroup);
+
+ nsCOMPtr<nsICategoryManager> catMan =
+ do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
+ NS_ENSURE_TRUE(catMan, NS_ERROR_NOT_AVAILABLE);
+ nsCString contractId;
+ nsresult rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", IMAGE_SVG_XML,
+ contractId);
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =
+ do_GetService(contractId.get());
+ NS_ENSURE_TRUE(docLoaderFactory, NS_ERROR_NOT_AVAILABLE);
+
+ nsCOMPtr<nsIContentViewer> viewer;
+ nsCOMPtr<nsIStreamListener> listener;
+ rv = docLoaderFactory->CreateInstance(
+ "external-resource", chan, newLoadGroup, nsLiteralCString(IMAGE_SVG_XML),
+ nullptr, nullptr, getter_AddRefs(listener), getter_AddRefs(viewer));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ NS_ENSURE_TRUE(viewer, NS_ERROR_UNEXPECTED);
+
+ // Create a navigation time object and pass it to the SVG document through
+ // the viewer.
+ // The timeline(DocumentTimeline, used in CSS animation) of this SVG
+ // document needs this navigation timing object for time computation, such
+ // as to calculate current time stamp based on the start time of navigation
+ // time object.
+ //
+ // For a root document, DocShell would do these sort of things
+ // automatically. Since there is no DocShell for this wrapped SVG document,
+ // we must set it up manually.
+ RefPtr<nsDOMNavigationTiming> timing = new nsDOMNavigationTiming(nullptr);
+ timing->NotifyNavigationStart(
+ nsDOMNavigationTiming::DocShellState::eInactive);
+ viewer->SetNavigationTiming(timing);
+
+ nsCOMPtr<nsIParser> parser = do_QueryInterface(listener);
+ NS_ENSURE_TRUE(parser, NS_ERROR_UNEXPECTED);
+
+ // XML-only, because this is for SVG content
+ nsCOMPtr<nsIContentSink> sink = parser->GetContentSink();
+ NS_ENSURE_TRUE(sink, NS_ERROR_UNEXPECTED);
+
+ listener.swap(mListener);
+ viewer.forget(aViewer);
+ newLoadGroup.forget(aLoadGroup);
+
+ RegisterForXPCOMShutdown();
+ return NS_OK;
+}
+
+void SVGDocumentWrapper::RegisterForXPCOMShutdown() {
+ MOZ_ASSERT(!mRegisteredForXPCOMShutdown, "re-registering for XPCOM shutdown");
+ // Listen for xpcom-shutdown so that we can drop references to our
+ // helper-document at that point. (Otherwise, we won't get cleaned up
+ // until imgLoader::Shutdown, which can happen after the JAR service
+ // and RDF service have been unregistered.)
+ nsresult rv;
+ nsCOMPtr<nsIObserverService> obsSvc = do_GetService(OBSERVER_SVC_CID, &rv);
+ if (NS_FAILED(rv) || NS_FAILED(obsSvc->AddObserver(
+ this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true))) {
+ NS_WARNING("Failed to register as observer of XPCOM shutdown");
+ } else {
+ mRegisteredForXPCOMShutdown = true;
+ }
+}
+
+void SVGDocumentWrapper::UnregisterForXPCOMShutdown() {
+ MOZ_ASSERT(mRegisteredForXPCOMShutdown,
+ "unregistering for XPCOM shutdown w/out being registered");
+
+ nsresult rv;
+ nsCOMPtr<nsIObserverService> obsSvc = do_GetService(OBSERVER_SVC_CID, &rv);
+ if (NS_FAILED(rv) ||
+ NS_FAILED(obsSvc->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
+ NS_WARNING("Failed to unregister as observer of XPCOM shutdown");
+ } else {
+ mRegisteredForXPCOMShutdown = false;
+ }
+}
+
+void SVGDocumentWrapper::FlushLayout() {
+ if (SVGDocument* doc = GetDocument()) {
+ doc->FlushPendingNotifications(FlushType::Layout);
+ }
+}
+
+SVGDocument* SVGDocumentWrapper::GetDocument() {
+ if (!mViewer) {
+ return nullptr;
+ }
+ Document* doc = mViewer->GetDocument();
+ if (!doc) {
+ return nullptr;
+ }
+ return doc->AsSVGDocument();
+}
+
+SVGSVGElement* SVGDocumentWrapper::GetRootSVGElem() {
+ if (!mViewer) {
+ return nullptr; // Can happen during destruction
+ }
+
+ Document* doc = mViewer->GetDocument();
+ if (!doc) {
+ return nullptr; // Can happen during destruction
+ }
+
+ Element* rootElem = mViewer->GetDocument()->GetRootElement();
+ if (!rootElem || !rootElem->IsSVGElement(nsGkAtoms::svg)) {
+ return nullptr;
+ }
+
+ return static_cast<SVGSVGElement*>(rootElem);
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/SVGDocumentWrapper.h b/image/SVGDocumentWrapper.h
new file mode 100644
index 0000000000..75924a4ea5
--- /dev/null
+++ b/image/SVGDocumentWrapper.h
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* This class wraps an SVG document, for use by VectorImage objects. */
+
+#ifndef mozilla_image_SVGDocumentWrapper_h
+#define mozilla_image_SVGDocumentWrapper_h
+
+#include "mozilla/Attributes.h"
+
+#include "nsCOMPtr.h"
+#include "nsIStreamListener.h"
+#include "nsIObserver.h"
+#include "nsIContentViewer.h"
+#include "nsWeakReference.h"
+#include "nsSize.h"
+
+class nsIRequest;
+class nsILoadGroup;
+class nsIFrame;
+
+#define OBSERVER_SVC_CID "@mozilla.org/observer-service;1"
+
+namespace mozilla {
+class PresShell;
+namespace dom {
+class SVGSVGElement;
+class SVGDocument;
+} // namespace dom
+
+namespace image {
+class AutoRestoreSVGState;
+
+class SVGDocumentWrapper final : public nsIStreamListener,
+ public nsIObserver,
+ public nsSupportsWeakReference {
+ public:
+ SVGDocumentWrapper();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSISTREAMLISTENER
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSIOBSERVER
+
+ enum Dimension { eWidth, eHeight };
+
+ /**
+ * Returns the wrapped document, or nullptr on failure. (No AddRef.)
+ */
+ mozilla::dom::SVGDocument* GetDocument();
+
+ /**
+ * Returns the root <svg> element for the wrapped document, or nullptr on
+ * failure.
+ */
+ mozilla::dom::SVGSVGElement* GetRootSVGElem();
+
+ /**
+ * Returns the root nsIFrame* for the wrapped document, or nullptr on failure.
+ *
+ * @return the root nsIFrame* for the wrapped document, or nullptr on failure.
+ */
+ nsIFrame* GetRootLayoutFrame();
+
+ /**
+ * Returns the mozilla::PresShell for the wrapped document.
+ */
+ inline mozilla::PresShell* GetPresShell() { return mViewer->GetPresShell(); }
+
+ /**
+ * Modifier to update the viewport dimensions of the wrapped document. This
+ * method performs a synchronous "FlushType::Layout" on the wrapped document,
+ * since a viewport-change affects layout.
+ *
+ * @param aViewportSize The new viewport dimensions.
+ */
+ void UpdateViewportBounds(const nsIntSize& aViewportSize);
+
+ /**
+ * If an SVG image's helper document has a pending notification for an
+ * override on the root node's "preserveAspectRatio" attribute, then this
+ * method will flush that notification so that the image can paint correctly.
+ * (First, though, it sets the mIgnoreInvalidation flag so that we won't
+ * notify the image's observers and trigger unwanted repaint-requests.)
+ */
+ void FlushImageTransformInvalidation();
+
+ /**
+ * Returns a bool indicating whether the document has any SMIL animations.
+ *
+ * @return true if the document has any SMIL animations. Else, false.
+ */
+ bool IsAnimated();
+
+ /**
+ * Indicates whether we should currently ignore rendering invalidations sent
+ * from the wrapped SVG doc.
+ *
+ * @return true if we should ignore invalidations sent from this SVG doc.
+ */
+ bool ShouldIgnoreInvalidation() { return mIgnoreInvalidation; }
+
+ /**
+ * Returns a bool indicating whether the document is currently drawing.
+ *
+ * @return true if the document is drawing. Else, false.
+ */
+ bool IsDrawing() const { return mIsDrawing; }
+
+ /**
+ * Methods to control animation.
+ */
+ void StartAnimation();
+ void StopAnimation();
+ void ResetAnimation();
+ float GetCurrentTimeAsFloat();
+ void SetCurrentTime(float aTime);
+ void TickRefreshDriver();
+
+ /**
+ * Force a layout flush of the underlying SVG document.
+ */
+ void FlushLayout();
+
+ private:
+ friend class AutoRestoreSVGState;
+
+ ~SVGDocumentWrapper();
+
+ nsresult SetupViewer(nsIRequest* aRequest, nsIContentViewer** aViewer,
+ nsILoadGroup** aLoadGroup);
+ void DestroyViewer();
+ void RegisterForXPCOMShutdown();
+ void UnregisterForXPCOMShutdown();
+
+ nsCOMPtr<nsIContentViewer> mViewer;
+ nsCOMPtr<nsILoadGroup> mLoadGroup;
+ nsCOMPtr<nsIStreamListener> mListener;
+ bool mIgnoreInvalidation;
+ bool mRegisteredForXPCOMShutdown;
+ bool mIsDrawing;
+};
+
+} // namespace image
+} // namespace mozilla
+
+/**
+ * Casting SVGDocumentWrapper to nsISupports is ambiguous. This method handles
+ * that.
+ */
+inline nsISupports* ToSupports(mozilla::image::SVGDocumentWrapper* p) {
+ return NS_ISUPPORTS_CAST(nsSupportsWeakReference*, p);
+}
+
+#endif // mozilla_image_SVGDocumentWrapper_h
diff --git a/image/SVGDrawingCallback.h b/image/SVGDrawingCallback.h
new file mode 100644
index 0000000000..ea06fbc64f
--- /dev/null
+++ b/image/SVGDrawingCallback.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_SVGDrawingCallback_h
+#define mozilla_image_SVGDrawingCallback_h
+
+#include "gfxDrawable.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/gfx/Types.h"
+
+namespace mozilla {
+namespace image {
+class SVGDocumentWrapper;
+
+class SVGDrawingCallback final : public gfxDrawingCallback {
+ public:
+ SVGDrawingCallback(SVGDocumentWrapper* aSVGDocumentWrapper,
+ const gfx::IntSize& aViewportSize,
+ const gfx::IntSize& aSize, uint32_t aImageFlags);
+
+ ~SVGDrawingCallback();
+
+ bool operator()(gfxContext* aContext, const gfxRect& aFillRect,
+ const gfx::SamplingFilter aSamplingFilter,
+ const gfxMatrix& aTransform) override;
+
+ private:
+ RefPtr<SVGDocumentWrapper> mSVGDocumentWrapper;
+ const gfx::IntSize mViewportSize;
+ const gfx::IntSize mSize;
+ uint32_t mImageFlags;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_SVGDrawingCallback_h
diff --git a/image/SVGDrawingParameters.h b/image/SVGDrawingParameters.h
new file mode 100644
index 0000000000..fa98162139
--- /dev/null
+++ b/image/SVGDrawingParameters.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_SVGDrawingParameters_h
+#define mozilla_image_SVGDrawingParameters_h
+
+#include "gfxContext.h"
+#include "gfxTypes.h"
+#include "ImageRegion.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/gfx/Types.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/SVGImageContext.h"
+#include "nsSize.h"
+
+namespace mozilla {
+namespace image {
+
+struct SVGDrawingParameters {
+ typedef mozilla::gfx::IntSize IntSize;
+ typedef mozilla::gfx::SamplingFilter SamplingFilter;
+
+ SVGDrawingParameters(gfxContext* aContext, const nsIntSize& aRasterSize,
+ const nsIntSize& aDrawSize, const ImageRegion& aRegion,
+ SamplingFilter aSamplingFilter,
+ const SVGImageContext& aSVGContext, float aAnimationTime,
+ uint32_t aFlags, float aOpacity)
+ : context(aContext),
+ size(aRasterSize),
+ drawSize(aDrawSize),
+ region(aRegion),
+ samplingFilter(aSamplingFilter),
+ svgContext(aSVGContext),
+ viewportSize(aRasterSize),
+ animationTime(aAnimationTime),
+ flags(aFlags),
+ opacity(aOpacity) {
+ if (auto sz = aSVGContext.GetViewportSize()) {
+ viewportSize = nsIntSize(sz->width, sz->height); // XXX losing unit
+ }
+ }
+
+ gfxContext* context;
+ IntSize size; // Size to rasterize a surface at.
+ IntSize drawSize; // Size to draw the given surface at.
+ ImageRegion region;
+ SamplingFilter samplingFilter;
+ const SVGImageContext& svgContext;
+ nsIntSize viewportSize;
+ float animationTime;
+ uint32_t flags;
+ gfxFloat opacity;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_SVGDrawingParameters_h
diff --git a/image/ScriptedNotificationObserver.cpp b/image/ScriptedNotificationObserver.cpp
new file mode 100644
index 0000000000..4797b182c3
--- /dev/null
+++ b/image/ScriptedNotificationObserver.cpp
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ScriptedNotificationObserver.h"
+#include "imgIScriptedNotificationObserver.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsContentUtils.h" // for nsAutoScriptBlocker
+
+namespace mozilla {
+namespace image {
+
+NS_IMPL_CYCLE_COLLECTION(ScriptedNotificationObserver, mInner)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ScriptedNotificationObserver)
+ NS_INTERFACE_MAP_ENTRY(imgINotificationObserver)
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptedNotificationObserver)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptedNotificationObserver)
+
+ScriptedNotificationObserver::ScriptedNotificationObserver(
+ imgIScriptedNotificationObserver* aInner)
+ : mInner(aInner) {}
+
+void ScriptedNotificationObserver::Notify(imgIRequest* aRequest, int32_t aType,
+ const nsIntRect* /*aUnused*/) {
+ // For now, we block (other) scripts from running to preserve the historical
+ // behavior from when ScriptedNotificationObserver::Notify was called as part
+ // of the observers list in nsImageLoadingContent::Notify. Now each
+ // ScriptedNotificationObserver has its own imgRequestProxy and thus gets
+ // Notify called directly by imagelib.
+ nsAutoScriptBlocker scriptBlocker;
+
+ if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
+ mInner->SizeAvailable(aRequest);
+ return;
+ }
+ if (aType == imgINotificationObserver::FRAME_UPDATE) {
+ mInner->FrameUpdate(aRequest);
+ return;
+ }
+ if (aType == imgINotificationObserver::FRAME_COMPLETE) {
+ mInner->FrameComplete(aRequest);
+ return;
+ }
+ if (aType == imgINotificationObserver::DECODE_COMPLETE) {
+ mInner->DecodeComplete(aRequest);
+ return;
+ }
+ if (aType == imgINotificationObserver::LOAD_COMPLETE) {
+ mInner->LoadComplete(aRequest);
+ return;
+ }
+ if (aType == imgINotificationObserver::DISCARD) {
+ mInner->Discard(aRequest);
+ return;
+ }
+ if (aType == imgINotificationObserver::IS_ANIMATED) {
+ mInner->IsAnimated(aRequest);
+ return;
+ }
+ if (aType == imgINotificationObserver::HAS_TRANSPARENCY) {
+ mInner->HasTransparency(aRequest);
+ return;
+ }
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/ScriptedNotificationObserver.h b/image/ScriptedNotificationObserver.h
new file mode 100644
index 0000000000..ceeafa532f
--- /dev/null
+++ b/image/ScriptedNotificationObserver.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_ScriptedNotificationObserver_h
+#define mozilla_image_ScriptedNotificationObserver_h
+
+#include "imgINotificationObserver.h"
+#include "nsCOMPtr.h"
+#include "nsCycleCollectionParticipant.h"
+
+class imgIScriptedNotificationObserver;
+
+namespace mozilla {
+namespace image {
+
+class ScriptedNotificationObserver : public imgINotificationObserver {
+ public:
+ explicit ScriptedNotificationObserver(
+ imgIScriptedNotificationObserver* aInner);
+
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_IMGINOTIFICATIONOBSERVER
+ NS_DECL_CYCLE_COLLECTION_CLASS(ScriptedNotificationObserver)
+
+ private:
+ virtual ~ScriptedNotificationObserver() {}
+ nsCOMPtr<imgIScriptedNotificationObserver> mInner;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_ScriptedNotificationObserver_h
diff --git a/image/ShutdownTracker.cpp b/image/ShutdownTracker.cpp
new file mode 100644
index 0000000000..4eef66e52e
--- /dev/null
+++ b/image/ShutdownTracker.cpp
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ShutdownTracker.h"
+
+#include "mozilla/Services.h"
+#include "nsIObserver.h"
+#include "nsIObserverService.h"
+
+namespace mozilla {
+namespace image {
+
+class ShutdownTrackerImpl;
+
+///////////////////////////////////////////////////////////////////////////////
+// Static Data
+///////////////////////////////////////////////////////////////////////////////
+
+// Whether we've observed shutdown starting yet.
+static bool sShutdownHasStarted = false;
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementation
+///////////////////////////////////////////////////////////////////////////////
+
+struct ShutdownObserver : public nsIObserver {
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD Observe(nsISupports*, const char* aTopic,
+ const char16_t*) override {
+ if (strcmp(aTopic, "xpcom-will-shutdown") != 0) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIObserverService> os = services::GetObserverService();
+ if (os) {
+ os->RemoveObserver(this, "xpcom-will-shutdown");
+ }
+
+ sShutdownHasStarted = true;
+ return NS_OK;
+ }
+
+ private:
+ virtual ~ShutdownObserver() {}
+};
+
+NS_IMPL_ISUPPORTS(ShutdownObserver, nsIObserver)
+
+///////////////////////////////////////////////////////////////////////////////
+// Public API
+///////////////////////////////////////////////////////////////////////////////
+
+/* static */
+void ShutdownTracker::Initialize() {
+ nsCOMPtr<nsIObserverService> os = services::GetObserverService();
+ if (os) {
+ os->AddObserver(new ShutdownObserver, "xpcom-will-shutdown", false);
+ }
+}
+
+/* static */
+bool ShutdownTracker::ShutdownHasStarted() { return sShutdownHasStarted; }
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/ShutdownTracker.h b/image/ShutdownTracker.h
new file mode 100644
index 0000000000..9e5237cc3d
--- /dev/null
+++ b/image/ShutdownTracker.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * ShutdownTracker is an imagelib-global service that allows callers to check
+ * whether shutdown has started.
+ */
+
+#ifndef mozilla_image_ShutdownTracker_h
+#define mozilla_image_ShutdownTracker_h
+
+namespace mozilla {
+namespace image {
+
+/**
+ * ShutdownTracker is an imagelib-global service that allows callers to check
+ * whether shutdown has started. It exists to avoid the need for registering
+ * many 'xpcom-will-shutdown' notification observers on short-lived objects,
+ * which would have an unnecessary performance cost.
+ */
+struct ShutdownTracker {
+ /**
+ * Initialize static data. Called during imagelib module initialization.
+ */
+ static void Initialize();
+
+ /**
+ * Check whether shutdown has started. Callers can use this to check whether
+ * it's safe to access XPCOM services; if shutdown has started, such calls
+ * must be avoided.
+ *
+ * @return true if shutdown has already started.
+ */
+ static bool ShutdownHasStarted();
+
+ private:
+ virtual ~ShutdownTracker() = 0; // Forbid instantiation.
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_ShutdownTracker_h
diff --git a/image/SourceBuffer.cpp b/image/SourceBuffer.cpp
new file mode 100644
index 0000000000..682ba84f8f
--- /dev/null
+++ b/image/SourceBuffer.cpp
@@ -0,0 +1,706 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SourceBuffer.h"
+
+#include <algorithm>
+#include <cmath>
+#include <cstring>
+#include "mozilla/Likely.h"
+#include "nsIInputStream.h"
+#include "MainThreadUtils.h"
+#include "SurfaceCache.h"
+
+using std::max;
+using std::min;
+
+namespace mozilla {
+namespace image {
+
+//////////////////////////////////////////////////////////////////////////////
+// SourceBufferIterator implementation.
+//////////////////////////////////////////////////////////////////////////////
+
+SourceBufferIterator::~SourceBufferIterator() {
+ if (mOwner) {
+ mOwner->OnIteratorRelease();
+ }
+}
+
+SourceBufferIterator& SourceBufferIterator::operator=(
+ SourceBufferIterator&& aOther) {
+ if (mOwner) {
+ mOwner->OnIteratorRelease();
+ }
+
+ mOwner = std::move(aOther.mOwner);
+ mState = aOther.mState;
+ mData = aOther.mData;
+ mChunkCount = aOther.mChunkCount;
+ mByteCount = aOther.mByteCount;
+ mRemainderToRead = aOther.mRemainderToRead;
+
+ return *this;
+}
+
+SourceBufferIterator::State SourceBufferIterator::AdvanceOrScheduleResume(
+ size_t aRequestedBytes, IResumable* aConsumer) {
+ MOZ_ASSERT(mOwner);
+
+ if (MOZ_UNLIKELY(!HasMore())) {
+ MOZ_ASSERT_UNREACHABLE("Should not advance a completed iterator");
+ return COMPLETE;
+ }
+
+ // The range of data [mOffset, mOffset + mNextReadLength) has just been read
+ // by the caller (or at least they don't have any interest in it), so consume
+ // that data.
+ MOZ_ASSERT(mData.mIterating.mNextReadLength <=
+ mData.mIterating.mAvailableLength);
+ mData.mIterating.mOffset += mData.mIterating.mNextReadLength;
+ mData.mIterating.mAvailableLength -= mData.mIterating.mNextReadLength;
+
+ // An iterator can have a limit imposed on it to read only a subset of a
+ // source buffer. If it is present, we need to mimic the same behaviour as
+ // the owning SourceBuffer.
+ if (MOZ_UNLIKELY(mRemainderToRead != SIZE_MAX)) {
+ MOZ_ASSERT(mData.mIterating.mNextReadLength <= mRemainderToRead);
+ mRemainderToRead -= mData.mIterating.mNextReadLength;
+
+ if (MOZ_UNLIKELY(mRemainderToRead == 0)) {
+ mData.mIterating.mNextReadLength = 0;
+ SetComplete(NS_OK);
+ return COMPLETE;
+ }
+
+ if (MOZ_UNLIKELY(aRequestedBytes > mRemainderToRead)) {
+ aRequestedBytes = mRemainderToRead;
+ }
+ }
+
+ mData.mIterating.mNextReadLength = 0;
+
+ if (MOZ_LIKELY(mState == READY)) {
+ // If the caller wants zero bytes of data, that's easy enough; we just
+ // configured ourselves for a zero-byte read above! In theory we could do
+ // this even in the START state, but it's not important for performance and
+ // breaking the ability of callers to assert that the pointer returned by
+ // Data() is non-null doesn't seem worth it.
+ if (aRequestedBytes == 0) {
+ MOZ_ASSERT(mData.mIterating.mNextReadLength == 0);
+ return READY;
+ }
+
+ // Try to satisfy the request out of our local buffer. This is potentially
+ // much faster than requesting data from our owning SourceBuffer because we
+ // don't have to take the lock. Note that if we have anything at all in our
+ // local buffer, we use it to satisfy the request; @aRequestedBytes is just
+ // the *maximum* number of bytes we can return.
+ if (mData.mIterating.mAvailableLength > 0) {
+ return AdvanceFromLocalBuffer(aRequestedBytes);
+ }
+ }
+
+ // Our local buffer is empty, so we'll have to request data from our owning
+ // SourceBuffer.
+ return mOwner->AdvanceIteratorOrScheduleResume(*this, aRequestedBytes,
+ aConsumer);
+}
+
+bool SourceBufferIterator::RemainingBytesIsNoMoreThan(size_t aBytes) const {
+ MOZ_ASSERT(mOwner);
+ return mOwner->RemainingBytesIsNoMoreThan(*this, aBytes);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// SourceBuffer implementation.
+//////////////////////////////////////////////////////////////////////////////
+
+const size_t SourceBuffer::MIN_CHUNK_CAPACITY;
+const size_t SourceBuffer::MAX_CHUNK_CAPACITY;
+
+SourceBuffer::SourceBuffer()
+ : mMutex("image::SourceBuffer"), mConsumerCount(0), mCompacted(false) {}
+
+SourceBuffer::~SourceBuffer() {
+ MOZ_ASSERT(mConsumerCount == 0,
+ "SourceBuffer destroyed with active consumers");
+}
+
+nsresult SourceBuffer::AppendChunk(Maybe<Chunk>&& aChunk) {
+ mMutex.AssertCurrentThreadOwns();
+
+#ifdef DEBUG
+ if (mChunks.Length() > 0) {
+ NS_WARNING("Appending an extra chunk for SourceBuffer");
+ }
+#endif
+
+ if (MOZ_UNLIKELY(!aChunk)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ if (MOZ_UNLIKELY(aChunk->AllocationFailed())) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ if (MOZ_UNLIKELY(!mChunks.AppendElement(std::move(*aChunk), fallible))) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ return NS_OK;
+}
+
+Maybe<SourceBuffer::Chunk> SourceBuffer::CreateChunk(
+ size_t aCapacity, size_t aExistingCapacity /* = 0 */,
+ bool aRoundUp /* = true */) {
+ if (MOZ_UNLIKELY(aCapacity == 0)) {
+ MOZ_ASSERT_UNREACHABLE("Appending a chunk of zero size?");
+ return Nothing();
+ }
+
+ // Round up if requested.
+ size_t finalCapacity = aRoundUp ? RoundedUpCapacity(aCapacity) : aCapacity;
+
+ // Use the size of the SurfaceCache as an additional heuristic to avoid
+ // allocating huge buffers. Generally images do not get smaller when decoded,
+ // so if we could store the source data in the SurfaceCache, we assume that
+ // there's no way we'll be able to store the decoded version.
+ if (MOZ_UNLIKELY(!SurfaceCache::CanHold(finalCapacity + aExistingCapacity))) {
+ NS_WARNING(
+ "SourceBuffer refused to create chunk too large for SurfaceCache");
+ return Nothing();
+ }
+
+ return Some(Chunk(finalCapacity));
+}
+
+nsresult SourceBuffer::Compact() {
+ mMutex.AssertCurrentThreadOwns();
+
+ MOZ_ASSERT(mConsumerCount == 0, "Should have no consumers here");
+ MOZ_ASSERT(mWaitingConsumers.Length() == 0, "Shouldn't have waiters");
+ MOZ_ASSERT(mStatus, "Should be complete here");
+
+ // If we've tried to compact once, don't attempt again.
+ if (mCompacted) {
+ return NS_OK;
+ }
+
+ mCompacted = true;
+
+ // Compact our waiting consumers list, since we're complete and no future
+ // consumer will ever have to wait.
+ mWaitingConsumers.Compact();
+
+ // If we have no chunks, then there's nothing to compact.
+ if (mChunks.Length() < 1) {
+ return NS_OK;
+ }
+
+ // If we have one chunk, then we can compact if it has excess capacity.
+ if (mChunks.Length() == 1 && mChunks[0].Length() == mChunks[0].Capacity()) {
+ return NS_OK;
+ }
+
+ // If the last chunk has the maximum capacity, then we know the total size
+ // will be quite large and not worth consolidating. We can likely/cheapily
+ // trim the last chunk if it is too big however.
+ size_t capacity = mChunks.LastElement().Capacity();
+ if (capacity == MAX_CHUNK_CAPACITY) {
+ size_t lastLength = mChunks.LastElement().Length();
+ if (lastLength != capacity) {
+ mChunks.LastElement().SetCapacity(lastLength);
+ }
+ return NS_OK;
+ }
+
+ // We can compact our buffer. Determine the total length.
+ size_t length = 0;
+ for (uint32_t i = 0; i < mChunks.Length(); ++i) {
+ length += mChunks[i].Length();
+ }
+
+ // If our total length is zero (which means ExpectLength() got called, but no
+ // data ever actually got written) then just empty our chunk list.
+ if (MOZ_UNLIKELY(length == 0)) {
+ mChunks.Clear();
+ return NS_OK;
+ }
+
+ Chunk& mergeChunk = mChunks[0];
+ if (MOZ_UNLIKELY(!mergeChunk.SetCapacity(length))) {
+ NS_WARNING("Failed to reallocate chunk for SourceBuffer compacting - OOM?");
+ return NS_OK;
+ }
+
+ // Copy our old chunks into the newly reallocated first chunk.
+ for (uint32_t i = 1; i < mChunks.Length(); ++i) {
+ size_t offset = mergeChunk.Length();
+ MOZ_ASSERT(offset < mergeChunk.Capacity());
+ MOZ_ASSERT(offset + mChunks[i].Length() <= mergeChunk.Capacity());
+
+ memcpy(mergeChunk.Data() + offset, mChunks[i].Data(), mChunks[i].Length());
+ mergeChunk.AddLength(mChunks[i].Length());
+ }
+
+ MOZ_ASSERT(mergeChunk.Length() == mergeChunk.Capacity(),
+ "Compacted chunk has slack space");
+
+ // Remove the redundant chunks.
+ mChunks.RemoveLastElements(mChunks.Length() - 1);
+ mChunks.Compact();
+
+ return NS_OK;
+}
+
+/* static */
+size_t SourceBuffer::RoundedUpCapacity(size_t aCapacity) {
+ // Protect against overflow.
+ if (MOZ_UNLIKELY(SIZE_MAX - aCapacity < MIN_CHUNK_CAPACITY)) {
+ return aCapacity;
+ }
+
+ // Round up to the next multiple of MIN_CHUNK_CAPACITY (which should be the
+ // size of a page).
+ size_t roundedCapacity =
+ (aCapacity + MIN_CHUNK_CAPACITY - 1) & ~(MIN_CHUNK_CAPACITY - 1);
+ MOZ_ASSERT(roundedCapacity >= aCapacity, "Bad math?");
+ MOZ_ASSERT(roundedCapacity - aCapacity < MIN_CHUNK_CAPACITY, "Bad math?");
+
+ return roundedCapacity;
+}
+
+size_t SourceBuffer::FibonacciCapacityWithMinimum(size_t aMinCapacity) {
+ mMutex.AssertCurrentThreadOwns();
+
+ // We grow the source buffer using a Fibonacci growth rate. It will be capped
+ // at MAX_CHUNK_CAPACITY, unless the available data exceeds that.
+
+ size_t length = mChunks.Length();
+
+ if (length == 0 || aMinCapacity > MAX_CHUNK_CAPACITY) {
+ return aMinCapacity;
+ }
+
+ if (length == 1) {
+ return min(max(2 * mChunks[0].Capacity(), aMinCapacity),
+ MAX_CHUNK_CAPACITY);
+ }
+
+ return min(
+ max(mChunks[length - 1].Capacity() + mChunks[length - 2].Capacity(),
+ aMinCapacity),
+ MAX_CHUNK_CAPACITY);
+}
+
+void SourceBuffer::AddWaitingConsumer(IResumable* aConsumer) {
+ mMutex.AssertCurrentThreadOwns();
+
+ MOZ_ASSERT(!mStatus, "Waiting when we're complete?");
+
+ if (aConsumer) {
+ mWaitingConsumers.AppendElement(aConsumer);
+ }
+}
+
+void SourceBuffer::ResumeWaitingConsumers() {
+ mMutex.AssertCurrentThreadOwns();
+
+ if (mWaitingConsumers.Length() == 0) {
+ return;
+ }
+
+ for (uint32_t i = 0; i < mWaitingConsumers.Length(); ++i) {
+ mWaitingConsumers[i]->Resume();
+ }
+
+ mWaitingConsumers.Clear();
+}
+
+nsresult SourceBuffer::ExpectLength(size_t aExpectedLength) {
+ MOZ_ASSERT(aExpectedLength > 0, "Zero expected size?");
+
+ MutexAutoLock lock(mMutex);
+
+ if (MOZ_UNLIKELY(mStatus)) {
+ MOZ_ASSERT_UNREACHABLE("ExpectLength after SourceBuffer is complete");
+ return NS_OK;
+ }
+
+ if (MOZ_UNLIKELY(mChunks.Length() > 0)) {
+ MOZ_ASSERT_UNREACHABLE("Duplicate or post-Append call to ExpectLength");
+ return NS_OK;
+ }
+
+ if (MOZ_UNLIKELY(!SurfaceCache::CanHold(aExpectedLength))) {
+ NS_WARNING("SourceBuffer refused to store too large buffer");
+ return HandleError(NS_ERROR_INVALID_ARG);
+ }
+
+ size_t length = min(aExpectedLength, MAX_CHUNK_CAPACITY);
+ if (MOZ_UNLIKELY(NS_FAILED(AppendChunk(CreateChunk(length,
+ /* aExistingCapacity */ 0,
+ /* aRoundUp */ false))))) {
+ return HandleError(NS_ERROR_OUT_OF_MEMORY);
+ }
+
+ return NS_OK;
+}
+
+nsresult SourceBuffer::Append(const char* aData, size_t aLength) {
+ MOZ_ASSERT(aData, "Should have a buffer");
+ MOZ_ASSERT(aLength > 0, "Writing a zero-sized chunk");
+
+ size_t currentChunkCapacity = 0;
+ size_t currentChunkLength = 0;
+ char* currentChunkData = nullptr;
+ size_t currentChunkRemaining = 0;
+ size_t forCurrentChunk = 0;
+ size_t forNextChunk = 0;
+ size_t nextChunkCapacity = 0;
+ size_t totalCapacity = 0;
+
+ {
+ MutexAutoLock lock(mMutex);
+
+ if (MOZ_UNLIKELY(mStatus)) {
+ // This SourceBuffer is already complete; ignore further data.
+ return NS_ERROR_FAILURE;
+ }
+
+ if (MOZ_UNLIKELY(mChunks.Length() == 0)) {
+ if (MOZ_UNLIKELY(NS_FAILED(AppendChunk(CreateChunk(aLength))))) {
+ return HandleError(NS_ERROR_OUT_OF_MEMORY);
+ }
+ }
+
+ // Copy out the current chunk's information so we can release the lock.
+ // Note that this wouldn't be safe if multiple producers were allowed!
+ Chunk& currentChunk = mChunks.LastElement();
+ currentChunkCapacity = currentChunk.Capacity();
+ currentChunkLength = currentChunk.Length();
+ currentChunkData = currentChunk.Data();
+
+ // Partition this data between the current chunk and the next chunk.
+ // (Because we always allocate a chunk big enough to fit everything passed
+ // to Append, we'll never need more than those two chunks to store
+ // everything.)
+ currentChunkRemaining = currentChunkCapacity - currentChunkLength;
+ forCurrentChunk = min(aLength, currentChunkRemaining);
+ forNextChunk = aLength - forCurrentChunk;
+
+ // If we'll need another chunk, determine what its capacity should be while
+ // we still hold the lock.
+ nextChunkCapacity =
+ forNextChunk > 0 ? FibonacciCapacityWithMinimum(forNextChunk) : 0;
+
+ for (uint32_t i = 0; i < mChunks.Length(); ++i) {
+ totalCapacity += mChunks[i].Capacity();
+ }
+ }
+
+ // Write everything we can fit into the current chunk.
+ MOZ_ASSERT(currentChunkLength + forCurrentChunk <= currentChunkCapacity);
+ memcpy(currentChunkData + currentChunkLength, aData, forCurrentChunk);
+
+ // If there's something left, create a new chunk and write it there.
+ Maybe<Chunk> nextChunk;
+ if (forNextChunk > 0) {
+ MOZ_ASSERT(nextChunkCapacity >= forNextChunk, "Next chunk too small?");
+ nextChunk = CreateChunk(nextChunkCapacity, totalCapacity);
+ if (MOZ_LIKELY(nextChunk && !nextChunk->AllocationFailed())) {
+ memcpy(nextChunk->Data(), aData + forCurrentChunk, forNextChunk);
+ nextChunk->AddLength(forNextChunk);
+ }
+ }
+
+ // Update shared data structures.
+ {
+ MutexAutoLock lock(mMutex);
+
+ // Update the length of the current chunk.
+ Chunk& currentChunk = mChunks.LastElement();
+ MOZ_ASSERT(currentChunk.Data() == currentChunkData, "Multiple producers?");
+ MOZ_ASSERT(currentChunk.Length() == currentChunkLength,
+ "Multiple producers?");
+
+ currentChunk.AddLength(forCurrentChunk);
+
+ // If we created a new chunk, add it to the series.
+ if (forNextChunk > 0) {
+ if (MOZ_UNLIKELY(!nextChunk)) {
+ return HandleError(NS_ERROR_OUT_OF_MEMORY);
+ }
+
+ if (MOZ_UNLIKELY(NS_FAILED(AppendChunk(std::move(nextChunk))))) {
+ return HandleError(NS_ERROR_OUT_OF_MEMORY);
+ }
+ }
+
+ // Resume any waiting readers now that there's new data.
+ ResumeWaitingConsumers();
+ }
+
+ return NS_OK;
+}
+
+static nsresult AppendToSourceBuffer(nsIInputStream*, void* aClosure,
+ const char* aFromRawSegment, uint32_t,
+ uint32_t aCount, uint32_t* aWriteCount) {
+ SourceBuffer* sourceBuffer = static_cast<SourceBuffer*>(aClosure);
+
+ // Copy the source data. Unless we hit OOM, we squelch the return value here,
+ // because returning an error means that ReadSegments stops reading data, and
+ // we want to ensure that we read everything we get. If we hit OOM then we
+ // return a failed status to the caller.
+ nsresult rv = sourceBuffer->Append(aFromRawSegment, aCount);
+ if (rv == NS_ERROR_OUT_OF_MEMORY) {
+ return rv;
+ }
+
+ // Report that we wrote everything we got.
+ *aWriteCount = aCount;
+
+ return NS_OK;
+}
+
+nsresult SourceBuffer::AppendFromInputStream(nsIInputStream* aInputStream,
+ uint32_t aCount) {
+ uint32_t bytesRead;
+ nsresult rv = aInputStream->ReadSegments(AppendToSourceBuffer, this, aCount,
+ &bytesRead);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ if (bytesRead == 0) {
+ // The loading of the image has been canceled.
+ return NS_ERROR_FAILURE;
+ }
+
+ if (bytesRead != aCount) {
+ // Only some of the given data was read. We may have failed in
+ // SourceBuffer::Append but ReadSegments swallowed the error. Otherwise the
+ // stream itself failed to yield the data.
+ MutexAutoLock lock(mMutex);
+ if (mStatus) {
+ MOZ_ASSERT(NS_FAILED(*mStatus));
+ return *mStatus;
+ }
+
+ MOZ_ASSERT_UNREACHABLE("AppendToSourceBuffer should consume everything");
+ }
+
+ return rv;
+}
+
+void SourceBuffer::Complete(nsresult aStatus) {
+ MutexAutoLock lock(mMutex);
+
+ // When an error occurs internally (e.g. due to an OOM), we save the status.
+ // This will indirectly trigger a failure higher up and that will call
+ // SourceBuffer::Complete. Since it doesn't necessarily know we are already
+ // complete, it is safe to ignore.
+ if (mStatus && (MOZ_UNLIKELY(NS_SUCCEEDED(*mStatus) ||
+ aStatus != NS_IMAGELIB_ERROR_FAILURE))) {
+ MOZ_ASSERT_UNREACHABLE("Called Complete more than once");
+ return;
+ }
+
+ if (MOZ_UNLIKELY(NS_SUCCEEDED(aStatus) && IsEmpty())) {
+ // It's illegal to succeed without writing anything.
+ aStatus = NS_ERROR_FAILURE;
+ }
+
+ mStatus = Some(aStatus);
+
+ // Resume any waiting consumers now that we're complete.
+ ResumeWaitingConsumers();
+
+ // If we still have active consumers, just return.
+ if (mConsumerCount > 0) {
+ return;
+ }
+
+ // Attempt to compact our buffer down to a single chunk.
+ Compact();
+}
+
+bool SourceBuffer::IsComplete() {
+ MutexAutoLock lock(mMutex);
+ return bool(mStatus);
+}
+
+size_t SourceBuffer::SizeOfIncludingThisWithComputedFallback(
+ MallocSizeOf aMallocSizeOf) const {
+ MutexAutoLock lock(mMutex);
+
+ size_t n = aMallocSizeOf(this);
+ n += mChunks.ShallowSizeOfExcludingThis(aMallocSizeOf);
+
+ for (uint32_t i = 0; i < mChunks.Length(); ++i) {
+ size_t chunkSize = aMallocSizeOf(mChunks[i].Data());
+
+ if (chunkSize == 0) {
+ // We're on a platform where moz_malloc_size_of always returns 0.
+ chunkSize = mChunks[i].Capacity();
+ }
+
+ n += chunkSize;
+ }
+
+ return n;
+}
+
+SourceBufferIterator SourceBuffer::Iterator(size_t aReadLength) {
+ {
+ MutexAutoLock lock(mMutex);
+ mConsumerCount++;
+ }
+
+ return SourceBufferIterator(this, aReadLength);
+}
+
+void SourceBuffer::OnIteratorRelease() {
+ MutexAutoLock lock(mMutex);
+
+ MOZ_ASSERT(mConsumerCount > 0, "Consumer count doesn't add up");
+ mConsumerCount--;
+
+ // If we still have active consumers, or we're not complete yet, then return.
+ if (mConsumerCount > 0 || !mStatus) {
+ return;
+ }
+
+ // Attempt to compact our buffer down to a single chunk.
+ Compact();
+}
+
+bool SourceBuffer::RemainingBytesIsNoMoreThan(
+ const SourceBufferIterator& aIterator, size_t aBytes) const {
+ MutexAutoLock lock(mMutex);
+
+ // If we're not complete, we always say no.
+ if (!mStatus) {
+ return false;
+ }
+
+ // If the iterator's at the end, the answer is trivial.
+ if (!aIterator.HasMore()) {
+ return true;
+ }
+
+ uint32_t iteratorChunk = aIterator.mData.mIterating.mChunk;
+ size_t iteratorOffset = aIterator.mData.mIterating.mOffset;
+ size_t iteratorLength = aIterator.mData.mIterating.mAvailableLength;
+
+ // Include the bytes the iterator is currently pointing to in the limit, so
+ // that the current chunk doesn't have to be a special case.
+ size_t bytes = aBytes + iteratorOffset + iteratorLength;
+
+ // Count the length over all of our chunks, starting with the one that the
+ // iterator is currently pointing to. (This is O(N), but N is expected to be
+ // ~1, so it doesn't seem worth caching the length separately.)
+ size_t lengthSoFar = 0;
+ for (uint32_t i = iteratorChunk; i < mChunks.Length(); ++i) {
+ lengthSoFar += mChunks[i].Length();
+ if (lengthSoFar > bytes) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+SourceBufferIterator::State SourceBuffer::AdvanceIteratorOrScheduleResume(
+ SourceBufferIterator& aIterator, size_t aRequestedBytes,
+ IResumable* aConsumer) {
+ MutexAutoLock lock(mMutex);
+
+ MOZ_ASSERT(aIterator.HasMore(),
+ "Advancing a completed iterator and "
+ "AdvanceOrScheduleResume didn't catch it");
+
+ if (MOZ_UNLIKELY(mStatus && NS_FAILED(*mStatus))) {
+ // This SourceBuffer is complete due to an error; all reads fail.
+ return aIterator.SetComplete(*mStatus);
+ }
+
+ if (MOZ_UNLIKELY(mChunks.Length() == 0)) {
+ // We haven't gotten an initial chunk yet.
+ AddWaitingConsumer(aConsumer);
+ return aIterator.SetWaiting(!!aConsumer);
+ }
+
+ uint32_t iteratorChunkIdx = aIterator.mData.mIterating.mChunk;
+ MOZ_ASSERT(iteratorChunkIdx < mChunks.Length());
+
+ const Chunk& currentChunk = mChunks[iteratorChunkIdx];
+ size_t iteratorEnd = aIterator.mData.mIterating.mOffset +
+ aIterator.mData.mIterating.mAvailableLength;
+ MOZ_ASSERT(iteratorEnd <= currentChunk.Length());
+ MOZ_ASSERT(iteratorEnd <= currentChunk.Capacity());
+
+ if (iteratorEnd < currentChunk.Length()) {
+ // There's more data in the current chunk.
+ return aIterator.SetReady(iteratorChunkIdx, currentChunk.Data(),
+ iteratorEnd, currentChunk.Length() - iteratorEnd,
+ aRequestedBytes);
+ }
+
+ if (iteratorEnd == currentChunk.Capacity() &&
+ !IsLastChunk(iteratorChunkIdx)) {
+ // Advance to the next chunk.
+ const Chunk& nextChunk = mChunks[iteratorChunkIdx + 1];
+ return aIterator.SetReady(iteratorChunkIdx + 1, nextChunk.Data(), 0,
+ nextChunk.Length(), aRequestedBytes);
+ }
+
+ MOZ_ASSERT(IsLastChunk(iteratorChunkIdx), "Should've advanced");
+
+ if (mStatus) {
+ // There's no more data and this SourceBuffer completed successfully.
+ MOZ_ASSERT(NS_SUCCEEDED(*mStatus), "Handled failures earlier");
+ return aIterator.SetComplete(*mStatus);
+ }
+
+ // We're not complete, but there's no more data right now. Arrange to wake up
+ // the consumer when we get more data.
+ AddWaitingConsumer(aConsumer);
+ return aIterator.SetWaiting(!!aConsumer);
+}
+
+nsresult SourceBuffer::HandleError(nsresult aError) {
+ MOZ_ASSERT(NS_FAILED(aError), "Should have an error here");
+ MOZ_ASSERT(aError == NS_ERROR_OUT_OF_MEMORY || aError == NS_ERROR_INVALID_ARG,
+ "Unexpected error; may want to notify waiting readers, which "
+ "HandleError currently doesn't do");
+
+ mMutex.AssertCurrentThreadOwns();
+
+ NS_WARNING("SourceBuffer encountered an unrecoverable error");
+
+ // Record the error.
+ mStatus = Some(aError);
+
+ // Drop our references to waiting readers.
+ mWaitingConsumers.Clear();
+
+ return *mStatus;
+}
+
+bool SourceBuffer::IsEmpty() {
+ mMutex.AssertCurrentThreadOwns();
+ return mChunks.Length() == 0 || mChunks[0].Length() == 0;
+}
+
+bool SourceBuffer::IsLastChunk(uint32_t aChunk) {
+ mMutex.AssertCurrentThreadOwns();
+ return aChunk + 1 == mChunks.Length();
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/SourceBuffer.h b/image/SourceBuffer.h
new file mode 100644
index 0000000000..79188fb882
--- /dev/null
+++ b/image/SourceBuffer.h
@@ -0,0 +1,499 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * SourceBuffer is a single producer, multiple consumer data structure used for
+ * storing image source (compressed) data.
+ */
+
+#ifndef mozilla_image_sourcebuffer_h
+#define mozilla_image_sourcebuffer_h
+
+#include <algorithm>
+#include <utility>
+
+#include "mozilla/Maybe.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/Mutex.h"
+#include "mozilla/RefCounted.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/UniquePtr.h"
+#include "nsTArray.h"
+
+class nsIInputStream;
+
+namespace mozilla {
+namespace image {
+
+class SourceBuffer;
+
+/**
+ * IResumable is an interface for classes that can schedule themselves to resume
+ * their work later. An implementation of IResumable generally should post a
+ * runnable to some event target which continues the work of the task.
+ */
+struct IResumable {
+ MOZ_DECLARE_REFCOUNTED_TYPENAME(IResumable)
+
+ // Subclasses may or may not be XPCOM classes, so we just require that they
+ // implement AddRef and Release.
+ NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
+
+ virtual void Resume() = 0;
+
+ protected:
+ virtual ~IResumable() {}
+};
+
+/**
+ * SourceBufferIterator is a class that allows consumers of image source data to
+ * read the contents of a SourceBuffer sequentially.
+ *
+ * Consumers can advance through the SourceBuffer by calling
+ * AdvanceOrScheduleResume() repeatedly. After every advance, they should call
+ * check the return value, which will tell them the iterator's new state.
+ *
+ * If WAITING is returned, AdvanceOrScheduleResume() has arranged
+ * to call the consumer's Resume() method later, so the consumer should save its
+ * state if needed and stop running.
+ *
+ * If the iterator's new state is READY, then the consumer can call Data() and
+ * Length() to read new data from the SourceBuffer.
+ *
+ * Finally, in the COMPLETE state the consumer can call CompletionStatus() to
+ * get the status passed to SourceBuffer::Complete().
+ */
+class SourceBufferIterator final {
+ public:
+ enum State {
+ START, // The iterator is at the beginning of the buffer.
+ READY, // The iterator is pointing to new data.
+ WAITING, // The iterator is blocked and the caller must yield.
+ COMPLETE // The iterator is pointing to the end of the buffer.
+ };
+
+ explicit SourceBufferIterator(SourceBuffer* aOwner, size_t aReadLimit)
+ : mOwner(aOwner),
+ mState(START),
+ mChunkCount(0),
+ mByteCount(0),
+ mRemainderToRead(aReadLimit) {
+ MOZ_ASSERT(aOwner);
+ mData.mIterating.mChunk = 0;
+ mData.mIterating.mData = nullptr;
+ mData.mIterating.mOffset = 0;
+ mData.mIterating.mAvailableLength = 0;
+ mData.mIterating.mNextReadLength = 0;
+ }
+
+ SourceBufferIterator(SourceBufferIterator&& aOther)
+ : mOwner(std::move(aOther.mOwner)),
+ mState(aOther.mState),
+ mData(aOther.mData),
+ mChunkCount(aOther.mChunkCount),
+ mByteCount(aOther.mByteCount),
+ mRemainderToRead(aOther.mRemainderToRead) {}
+
+ ~SourceBufferIterator();
+
+ SourceBufferIterator& operator=(SourceBufferIterator&& aOther);
+
+ /**
+ * Returns true if there are no more than @aBytes remaining in the
+ * SourceBuffer. If the SourceBuffer is not yet complete, returns false.
+ */
+ bool RemainingBytesIsNoMoreThan(size_t aBytes) const;
+
+ /**
+ * Advances the iterator through the SourceBuffer if possible. Advances no
+ * more than @aRequestedBytes bytes. (Use SIZE_MAX to advance as much as
+ * possible.)
+ *
+ * This is a wrapper around AdvanceOrScheduleResume() that makes it clearer at
+ * the callsite when the no resuming is intended.
+ *
+ * @return State::READY if the iterator was successfully advanced.
+ * State::WAITING if the iterator could not be advanced because it's
+ * at the end of the underlying SourceBuffer, but the SourceBuffer
+ * may still receive additional data.
+ * State::COMPLETE if the iterator could not be advanced because it's
+ * at the end of the underlying SourceBuffer and the SourceBuffer is
+ * marked complete (i.e., it will never receive any additional
+ * data).
+ */
+ State Advance(size_t aRequestedBytes) {
+ return AdvanceOrScheduleResume(aRequestedBytes, nullptr);
+ }
+
+ /**
+ * Advances the iterator through the SourceBuffer if possible. Advances no
+ * more than @aRequestedBytes bytes. (Use SIZE_MAX to advance as much as
+ * possible.) If advancing is not possible and @aConsumer is not null,
+ * arranges to call the @aConsumer's Resume() method when more data is
+ * available.
+ *
+ * @return State::READY if the iterator was successfully advanced.
+ * State::WAITING if the iterator could not be advanced because it's
+ * at the end of the underlying SourceBuffer, but the SourceBuffer
+ * may still receive additional data. @aConsumer's Resume() method
+ * will be called when additional data is available.
+ * State::COMPLETE if the iterator could not be advanced because it's
+ * at the end of the underlying SourceBuffer and the SourceBuffer is
+ * marked complete (i.e., it will never receive any additional
+ * data).
+ */
+ State AdvanceOrScheduleResume(size_t aRequestedBytes, IResumable* aConsumer);
+
+ /// If at the end, returns the status passed to SourceBuffer::Complete().
+ nsresult CompletionStatus() const {
+ MOZ_ASSERT(mState == COMPLETE,
+ "Calling CompletionStatus() in the wrong state");
+ return mState == COMPLETE ? mData.mAtEnd.mStatus : NS_OK;
+ }
+
+ /// If we're ready to read, returns a pointer to the new data.
+ const char* Data() const {
+ MOZ_ASSERT(mState == READY, "Calling Data() in the wrong state");
+ return mState == READY ? mData.mIterating.mData + mData.mIterating.mOffset
+ : nullptr;
+ }
+
+ /// If we're ready to read, returns the length of the new data.
+ size_t Length() const {
+ MOZ_ASSERT(mState == READY, "Calling Length() in the wrong state");
+ return mState == READY ? mData.mIterating.mNextReadLength : 0;
+ }
+
+ /// If we're ready to read, returns whether or not everything available thus
+ /// far has been in the same contiguous buffer.
+ bool IsContiguous() const {
+ MOZ_ASSERT(mState == READY, "Calling IsContiguous() in the wrong state");
+ return mState == READY ? mData.mIterating.mChunk == 0 : false;
+ }
+
+ /// @return a count of the chunks we've advanced through.
+ uint32_t ChunkCount() const { return mChunkCount; }
+
+ /// @return a count of the bytes in all chunks we've advanced through.
+ size_t ByteCount() const { return mByteCount; }
+
+ /// @return the source buffer which owns the iterator.
+ SourceBuffer* Owner() const {
+ MOZ_ASSERT(mOwner);
+ return mOwner;
+ }
+
+ /// @return the current offset from the beginning of the buffer.
+ size_t Position() const {
+ return mByteCount - mData.mIterating.mAvailableLength;
+ }
+
+ private:
+ friend class SourceBuffer;
+
+ SourceBufferIterator(const SourceBufferIterator&) = delete;
+ SourceBufferIterator& operator=(const SourceBufferIterator&) = delete;
+
+ bool HasMore() const { return mState != COMPLETE; }
+
+ State AdvanceFromLocalBuffer(size_t aRequestedBytes) {
+ MOZ_ASSERT(mState == READY, "Advancing in the wrong state");
+ MOZ_ASSERT(mData.mIterating.mAvailableLength > 0,
+ "The local buffer shouldn't be empty");
+ MOZ_ASSERT(mData.mIterating.mNextReadLength == 0,
+ "Advancing without consuming previous data");
+
+ mData.mIterating.mNextReadLength =
+ std::min(mData.mIterating.mAvailableLength, aRequestedBytes);
+
+ return READY;
+ }
+
+ State SetReady(uint32_t aChunk, const char* aData, size_t aOffset,
+ size_t aAvailableLength, size_t aRequestedBytes) {
+ MOZ_ASSERT(mState != COMPLETE);
+ mState = READY;
+
+ // Prevent the iterator from reporting more data than it is allowed to read.
+ if (aAvailableLength > mRemainderToRead) {
+ aAvailableLength = mRemainderToRead;
+ }
+
+ // Update state.
+ mData.mIterating.mChunk = aChunk;
+ mData.mIterating.mData = aData;
+ mData.mIterating.mOffset = aOffset;
+ mData.mIterating.mAvailableLength = aAvailableLength;
+
+ // Update metrics.
+ mChunkCount++;
+ mByteCount += aAvailableLength;
+
+ // Attempt to advance by the requested number of bytes.
+ return AdvanceFromLocalBuffer(aRequestedBytes);
+ }
+
+ State SetWaiting(bool aHasConsumer) {
+ MOZ_ASSERT(mState != COMPLETE);
+ // Without a consumer, we won't know when to wake up precisely. Caller
+ // convention should mean that we don't try to advance unless we have
+ // written new data, but that doesn't mean we got enough.
+ MOZ_ASSERT(mState != WAITING || !aHasConsumer,
+ "Did we get a spurious wakeup somehow?");
+ return mState = WAITING;
+ }
+
+ State SetComplete(nsresult aStatus) {
+ mData.mAtEnd.mStatus = aStatus;
+ return mState = COMPLETE;
+ }
+
+ RefPtr<SourceBuffer> mOwner;
+
+ State mState;
+
+ /**
+ * This union contains our iteration state if we're still iterating (for
+ * states START, READY, and WAITING) and the status the SourceBuffer was
+ * completed with if we're in state COMPLETE.
+ */
+ union {
+ struct {
+ uint32_t mChunk; // Index of the chunk in SourceBuffer.
+ const char* mData; // Pointer to the start of the chunk.
+ size_t mOffset; // Current read position of the iterator relative to
+ // mData.
+ size_t mAvailableLength; // How many bytes remain unread in the chunk,
+ // relative to mOffset.
+ size_t
+ mNextReadLength; // How many bytes the last iterator advance
+ // requested to be read, so that we know much
+ // to increase mOffset and reduce mAvailableLength
+ // by when the next advance is requested.
+ } mIterating; // Cached info of the chunk currently iterating over.
+ struct {
+ nsresult mStatus; // Status code indicating if we read all the data.
+ } mAtEnd; // State info after iterator is complete.
+ } mData;
+
+ uint32_t mChunkCount; // Count of chunks observed, including current chunk.
+ size_t mByteCount; // Count of readable bytes observed, including unread
+ // bytes from the current chunk.
+ size_t mRemainderToRead; // Count of bytes left to read if there is a maximum
+ // imposed by the caller. SIZE_MAX if unlimited.
+};
+
+/**
+ * SourceBuffer is a parallel data structure used for storing image source
+ * (compressed) data.
+ *
+ * SourceBuffer is a single producer, multiple consumer data structure. The
+ * single producer calls Append() to append data to the buffer. In parallel,
+ * multiple consumers can call Iterator(), which returns a SourceBufferIterator
+ * that they can use to iterate through the buffer. The SourceBufferIterator
+ * returns a series of pointers which remain stable for lifetime of the
+ * SourceBuffer, and the data they point to is immutable, ensuring that the
+ * producer never interferes with the consumers.
+ *
+ * In order to avoid blocking, SourceBuffer works with SourceBufferIterator to
+ * keep a list of consumers which are waiting for new data, and to resume them
+ * when the producer appends more. All consumers must implement the IResumable
+ * interface to make this possible.
+ */
+class SourceBuffer final {
+ public:
+ MOZ_DECLARE_REFCOUNTED_TYPENAME(image::SourceBuffer)
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(image::SourceBuffer)
+
+ SourceBuffer();
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Producer methods.
+ //////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * If the producer knows how long the source data will be, it should call
+ * ExpectLength, which enables SourceBuffer to preallocate its buffer.
+ */
+ nsresult ExpectLength(size_t aExpectedLength);
+
+ /// Append the provided data to the buffer.
+ nsresult Append(const char* aData, size_t aLength);
+
+ /// Append the data available on the provided nsIInputStream to the buffer.
+ nsresult AppendFromInputStream(nsIInputStream* aInputStream, uint32_t aCount);
+
+ /**
+ * Mark the buffer complete, with a status that will be available to
+ * consumers. Further calls to Append() are forbidden after Complete().
+ */
+ void Complete(nsresult aStatus);
+
+ /// Returns true if the buffer is complete.
+ bool IsComplete();
+
+ /// Memory reporting.
+ size_t SizeOfIncludingThisWithComputedFallback(MallocSizeOf) const;
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Consumer methods.
+ //////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Returns an iterator to this SourceBuffer, which cannot read more than the
+ * given length.
+ */
+ SourceBufferIterator Iterator(size_t aReadLength = SIZE_MAX);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Consumer methods.
+ //////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * The minimum chunk capacity we'll allocate, if we don't know the correct
+ * capacity (which would happen because ExpectLength() wasn't called or gave
+ * us the wrong value). This is only exposed for use by tests; if normal code
+ * is using this, it's doing something wrong.
+ */
+ static const size_t MIN_CHUNK_CAPACITY = 4096;
+
+ /**
+ * The maximum chunk capacity we'll allocate. This was historically the
+ * maximum we would preallocate based on the network size. We may adjust it
+ * in the future based on the IMAGE_DECODE_CHUNKS telemetry to ensure most
+ * images remain in a single chunk.
+ */
+ static const size_t MAX_CHUNK_CAPACITY = 20 * 1024 * 1024;
+
+ private:
+ friend class SourceBufferIterator;
+
+ ~SourceBuffer();
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Chunk type and chunk-related methods.
+ //////////////////////////////////////////////////////////////////////////////
+
+ class Chunk final {
+ public:
+ explicit Chunk(size_t aCapacity) : mCapacity(aCapacity), mLength(0) {
+ MOZ_ASSERT(aCapacity > 0, "Creating zero-capacity chunk");
+ mData = static_cast<char*>(malloc(mCapacity));
+ }
+
+ ~Chunk() { free(mData); }
+
+ Chunk(Chunk&& aOther)
+ : mCapacity(aOther.mCapacity),
+ mLength(aOther.mLength),
+ mData(aOther.mData) {
+ aOther.mCapacity = aOther.mLength = 0;
+ aOther.mData = nullptr;
+ }
+
+ Chunk& operator=(Chunk&& aOther) {
+ free(mData);
+ mCapacity = aOther.mCapacity;
+ mLength = aOther.mLength;
+ mData = aOther.mData;
+ aOther.mCapacity = aOther.mLength = 0;
+ aOther.mData = nullptr;
+ return *this;
+ }
+
+ bool AllocationFailed() const { return !mData; }
+ size_t Capacity() const { return mCapacity; }
+ size_t Length() const { return mLength; }
+
+ char* Data() const {
+ MOZ_ASSERT(mData, "Allocation failed but nobody checked for it");
+ return mData;
+ }
+
+ void AddLength(size_t aAdditionalLength) {
+ MOZ_ASSERT(mLength + aAdditionalLength <= mCapacity);
+ mLength += aAdditionalLength;
+ }
+
+ bool SetCapacity(size_t aCapacity) {
+ MOZ_ASSERT(mData, "Allocation failed but nobody checked for it");
+ char* data = static_cast<char*>(realloc(mData, aCapacity));
+ if (!data) {
+ return false;
+ }
+
+ mData = data;
+ mCapacity = aCapacity;
+ return true;
+ }
+
+ private:
+ Chunk(const Chunk&) = delete;
+ Chunk& operator=(const Chunk&) = delete;
+
+ size_t mCapacity;
+ size_t mLength;
+ char* mData;
+ };
+
+ nsresult AppendChunk(Maybe<Chunk>&& aChunk) MOZ_REQUIRES(mMutex);
+ Maybe<Chunk> CreateChunk(size_t aCapacity, size_t aExistingCapacity = 0,
+ bool aRoundUp = true);
+ nsresult Compact() MOZ_REQUIRES(mMutex);
+ static size_t RoundedUpCapacity(size_t aCapacity);
+ size_t FibonacciCapacityWithMinimum(size_t aMinCapacity) MOZ_REQUIRES(mMutex);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Iterator / consumer methods.
+ //////////////////////////////////////////////////////////////////////////////
+
+ void AddWaitingConsumer(IResumable* aConsumer) MOZ_REQUIRES(mMutex);
+ void ResumeWaitingConsumers() MOZ_REQUIRES(mMutex);
+
+ typedef SourceBufferIterator::State State;
+
+ State AdvanceIteratorOrScheduleResume(SourceBufferIterator& aIterator,
+ size_t aRequestedBytes,
+ IResumable* aConsumer);
+ bool RemainingBytesIsNoMoreThan(const SourceBufferIterator& aIterator,
+ size_t aBytes) const;
+
+ void OnIteratorRelease();
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Helper methods.
+ //////////////////////////////////////////////////////////////////////////////
+
+ nsresult HandleError(nsresult aError) MOZ_REQUIRES(mMutex);
+ bool IsEmpty() MOZ_REQUIRES(mMutex);
+ bool IsLastChunk(uint32_t aChunk) MOZ_REQUIRES(mMutex);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Member variables.
+ //////////////////////////////////////////////////////////////////////////////
+
+ /// All private members are protected by mMutex.
+ mutable Mutex mMutex;
+
+ /// The data in this SourceBuffer, stored as a series of Chunks.
+ AutoTArray<Chunk, 1> mChunks MOZ_GUARDED_BY(mMutex);
+
+ /// Consumers which are waiting to be notified when new data is available.
+ nsTArray<RefPtr<IResumable>> mWaitingConsumers MOZ_GUARDED_BY(mMutex);
+
+ /// If present, marks this SourceBuffer complete with the given final status.
+ Maybe<nsresult> mStatus MOZ_GUARDED_BY(mMutex);
+
+ /// Count of active consumers.
+ uint32_t mConsumerCount MOZ_GUARDED_BY(mMutex);
+
+ /// True if compacting has been performed.
+ bool mCompacted MOZ_GUARDED_BY(mMutex);
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_sourcebuffer_h
diff --git a/image/StreamingLexer.h b/image/StreamingLexer.h
new file mode 100644
index 0000000000..06dbabde1c
--- /dev/null
+++ b/image/StreamingLexer.h
@@ -0,0 +1,751 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * StreamingLexer is a lexing framework designed to make it simple to write
+ * image decoders without worrying about the details of how the data is arriving
+ * from the network.
+ */
+
+#ifndef mozilla_image_StreamingLexer_h
+#define mozilla_image_StreamingLexer_h
+
+#include <algorithm>
+#include <cstdint>
+#include <utility>
+
+#include "SourceBuffer.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/Variant.h"
+#include "mozilla/Vector.h"
+
+namespace mozilla {
+namespace image {
+
+/// Buffering behaviors for StreamingLexer transitions.
+enum class BufferingStrategy {
+ BUFFERED, // Data will be buffered and processed in one chunk.
+ UNBUFFERED // Data will be processed as it arrives, in multiple chunks.
+};
+
+/// Control flow behaviors for StreamingLexer transitions.
+enum class ControlFlowStrategy {
+ CONTINUE, // If there's enough data, proceed to the next state immediately.
+ YIELD // Yield to the caller before proceeding to the next state.
+};
+
+/// Possible terminal states for the lexer.
+enum class TerminalState { SUCCESS, FAILURE };
+
+/// Possible yield reasons for the lexer.
+enum class Yield {
+ NEED_MORE_DATA, // The lexer cannot continue without more data.
+ OUTPUT_AVAILABLE // There is output available for the caller to consume.
+};
+
+/// The result of a call to StreamingLexer::Lex().
+typedef Variant<TerminalState, Yield> LexerResult;
+
+/**
+ * LexerTransition is a type used to give commands to the lexing framework.
+ * Code that uses StreamingLexer can create LexerTransition values using the
+ * static methods on Transition, and then return them to the lexing framework
+ * for execution.
+ */
+template <typename State>
+class LexerTransition {
+ public:
+ // This is implicit so that Terminate{Success,Failure}() can return a
+ // TerminalState and have it implicitly converted to a
+ // LexerTransition<State>, which avoids the need for a "<State>"
+ // qualification to the Terminate{Success,Failure}() callsite.
+ MOZ_IMPLICIT LexerTransition(TerminalState aFinalState)
+ : mNextState(aFinalState) {}
+
+ bool NextStateIsTerminal() const {
+ return mNextState.template is<TerminalState>();
+ }
+
+ TerminalState NextStateAsTerminal() const {
+ return mNextState.template as<TerminalState>();
+ }
+
+ State NextState() const {
+ return mNextState.template as<NonTerminalState>().mState;
+ }
+
+ State UnbufferedState() const {
+ return *mNextState.template as<NonTerminalState>().mUnbufferedState;
+ }
+
+ size_t Size() const {
+ return mNextState.template as<NonTerminalState>().mSize;
+ }
+
+ BufferingStrategy Buffering() const {
+ return mNextState.template as<NonTerminalState>().mBufferingStrategy;
+ }
+
+ ControlFlowStrategy ControlFlow() const {
+ return mNextState.template as<NonTerminalState>().mControlFlowStrategy;
+ }
+
+ private:
+ friend struct Transition;
+
+ LexerTransition(State aNextState, const Maybe<State>& aUnbufferedState,
+ size_t aSize, BufferingStrategy aBufferingStrategy,
+ ControlFlowStrategy aControlFlowStrategy)
+ : mNextState(NonTerminalState(aNextState, aUnbufferedState, aSize,
+ aBufferingStrategy, aControlFlowStrategy)) {
+ }
+
+ struct NonTerminalState {
+ State mState;
+ Maybe<State> mUnbufferedState;
+ size_t mSize;
+ BufferingStrategy mBufferingStrategy;
+ ControlFlowStrategy mControlFlowStrategy;
+
+ NonTerminalState(State aState, const Maybe<State>& aUnbufferedState,
+ size_t aSize, BufferingStrategy aBufferingStrategy,
+ ControlFlowStrategy aControlFlowStrategy)
+ : mState(aState),
+ mUnbufferedState(aUnbufferedState),
+ mSize(aSize),
+ mBufferingStrategy(aBufferingStrategy),
+ mControlFlowStrategy(aControlFlowStrategy) {
+ MOZ_ASSERT_IF(mBufferingStrategy == BufferingStrategy::UNBUFFERED,
+ mUnbufferedState);
+ MOZ_ASSERT_IF(mUnbufferedState,
+ mBufferingStrategy == BufferingStrategy::UNBUFFERED);
+ }
+ };
+
+ Variant<NonTerminalState, TerminalState> mNextState;
+};
+
+struct Transition {
+ /// Transition to @aNextState, buffering @aSize bytes of data.
+ template <typename State>
+ static LexerTransition<State> To(const State& aNextState, size_t aSize) {
+ return LexerTransition<State>(aNextState, Nothing(), aSize,
+ BufferingStrategy::BUFFERED,
+ ControlFlowStrategy::CONTINUE);
+ }
+
+ /// Yield to the caller, transitioning to @aNextState when Lex() is next
+ /// invoked. The same data that was delivered for the current state will be
+ /// delivered again.
+ template <typename State>
+ static LexerTransition<State> ToAfterYield(const State& aNextState) {
+ return LexerTransition<State>(aNextState, Nothing(), 0,
+ BufferingStrategy::BUFFERED,
+ ControlFlowStrategy::YIELD);
+ }
+
+ /**
+ * Transition to @aNextState via @aUnbufferedState, reading @aSize bytes of
+ * data unbuffered.
+ *
+ * The unbuffered data will be delivered in state @aUnbufferedState, which may
+ * be invoked repeatedly until all @aSize bytes have been delivered. Then,
+ * @aNextState will be invoked with no data. No state transitions are allowed
+ * from @aUnbufferedState except for transitions to a terminal state, so
+ * @aNextState will always be reached unless lexing terminates early.
+ */
+ template <typename State>
+ static LexerTransition<State> ToUnbuffered(const State& aNextState,
+ const State& aUnbufferedState,
+ size_t aSize) {
+ return LexerTransition<State>(aNextState, Some(aUnbufferedState), aSize,
+ BufferingStrategy::UNBUFFERED,
+ ControlFlowStrategy::CONTINUE);
+ }
+
+ /**
+ * Continue receiving unbuffered data. @aUnbufferedState should be the same
+ * state as the @aUnbufferedState specified in the preceding call to
+ * ToUnbuffered().
+ *
+ * This should be used during an unbuffered read initiated by ToUnbuffered().
+ */
+ template <typename State>
+ static LexerTransition<State> ContinueUnbuffered(
+ const State& aUnbufferedState) {
+ return LexerTransition<State>(aUnbufferedState, Nothing(), 0,
+ BufferingStrategy::BUFFERED,
+ ControlFlowStrategy::CONTINUE);
+ }
+
+ /**
+ * Continue receiving unbuffered data. @aUnbufferedState should be the same
+ * state as the @aUnbufferedState specified in the preceding call to
+ * ToUnbuffered(). @aSize indicates the amount of data that has already been
+ * consumed; the next state will receive the same data that was delivered to
+ * the current state, without the first @aSize bytes.
+ *
+ * This should be used during an unbuffered read initiated by ToUnbuffered().
+ */
+ template <typename State>
+ static LexerTransition<State> ContinueUnbufferedAfterYield(
+ const State& aUnbufferedState, size_t aSize) {
+ return LexerTransition<State>(aUnbufferedState, Nothing(), aSize,
+ BufferingStrategy::BUFFERED,
+ ControlFlowStrategy::YIELD);
+ }
+
+ /**
+ * Terminate lexing, ending up in terminal state SUCCESS. (The implicit
+ * LexerTransition constructor will convert the result to a LexerTransition
+ * as needed.)
+ *
+ * No more data will be delivered after this function is used.
+ */
+ static TerminalState TerminateSuccess() { return TerminalState::SUCCESS; }
+
+ /**
+ * Terminate lexing, ending up in terminal state FAILURE. (The implicit
+ * LexerTransition constructor will convert the result to a LexerTransition
+ * as needed.)
+ *
+ * No more data will be delivered after this function is used.
+ */
+ static TerminalState TerminateFailure() { return TerminalState::FAILURE; }
+
+ private:
+ Transition();
+};
+
+/**
+ * StreamingLexer is a lexing framework designed to make it simple to write
+ * image decoders without worrying about the details of how the data is arriving
+ * from the network.
+ *
+ * To use StreamingLexer:
+ *
+ * - Create a State type. This should be an |enum class| listing all of the
+ * states that you can be in while lexing the image format you're trying to
+ * read.
+ *
+ * - Add an instance of StreamingLexer<State> to your decoder class. Initialize
+ * it with a Transition::To() the state that you want to start lexing in, and
+ * a Transition::To() the state you'd like to use to handle truncated data.
+ *
+ * - In your decoder's DoDecode() method, call Lex(), passing in the input
+ * data and length that are passed to DoDecode(). You also need to pass
+ * a lambda which dispatches to lexing code for each state based on the State
+ * value that's passed in. The lambda generally should just continue a
+ * |switch| statement that calls different methods for each State value. Each
+ * method should return a LexerTransition<State>, which the lambda should
+ * return in turn.
+ *
+ * - Write the methods that actually implement lexing for your image format.
+ * These methods should return either Transition::To(), to move on to another
+ * state, or Transition::Terminate{Success,Failure}(), if lexing has
+ * terminated in either success or failure. (There are also additional
+ * transitions for unbuffered reads; see below.)
+ *
+ * That's the basics. The StreamingLexer will track your position in the input
+ * and buffer enough data so that your lexing methods can process everything in
+ * one pass. Lex() returns Yield::NEED_MORE_DATA if more data is needed, in
+ * which case you should just return from DoDecode(). If lexing reaches a
+ * terminal state, Lex() returns TerminalState::SUCCESS or
+ * TerminalState::FAILURE, and you can check which one to determine if lexing
+ * succeeded or failed and do any necessary cleanup.
+ *
+ * Sometimes, the input data is truncated. StreamingLexer will notify you when
+ * this happens by invoking the truncated data state you passed to the
+ * constructor. At this point you can attempt to recover and return
+ * TerminalState::SUCCESS or TerminalState::FAILURE, depending on whether you
+ * were successful. Note that you can't return anything other than a terminal
+ * state in this situation, since there's no more data to read. For the same
+ * reason, your truncated data state shouldn't require any data. (That is, the
+ * @aSize argument you pass to Transition::To() must be zero.) Violating these
+ * requirements will trigger assertions and an immediate transition to
+ * TerminalState::FAILURE.
+ *
+ * Some lexers may want to *avoid* buffering in some cases, and just process the
+ * data as it comes in. This is useful if, for example, you just want to skip
+ * over a large section of data; there's no point in buffering data you're just
+ * going to ignore.
+ *
+ * You can begin an unbuffered read with Transition::ToUnbuffered(). This works
+ * a little differently than Transition::To() in that you specify *two* states.
+ * The @aUnbufferedState argument specifies a state that will be called
+ * repeatedly with unbuffered data, as soon as it arrives. The implementation
+ * for that state should return either a transition to a terminal state, or a
+ * Transition::ContinueUnbuffered() to the same @aUnbufferedState. (From a
+ * technical perspective, it's not necessary to specify the state again, but
+ * it's helpful to human readers.) Once the amount of data requested in the
+ * original call to Transition::ToUnbuffered() has been delivered, Lex() will
+ * transition to the @aNextState state specified via Transition::ToUnbuffered().
+ * That state will be invoked with *no* data; it's just called to signal that
+ * the unbuffered read is over.
+ *
+ * It's sometimes useful for a lexer to provide incremental results, rather
+ * than simply running to completion and presenting all its output at once. For
+ * example, when decoding animated images, it may be useful to produce each
+ * frame incrementally. StreamingLexer supports this by allowing a lexer to
+ * yield.
+ *
+ * To yield back to the caller, a state implementation can simply return
+ * Transition::ToAfterYield(). ToAfterYield()'s @aNextState argument specifies
+ * the next state that the lexer should transition to, just like when using
+ * Transition::To(), but there are two differences. One is that Lex() will
+ * return to the caller before processing any more data when it encounters a
+ * yield transition. This provides an opportunity for the caller to interact
+ * with the lexer's intermediate results. The second difference is that
+ * @aNextState will be called with *the same data as the state that you returned
+ * Transition::ToAfterYield() from*. This allows a lexer to partially consume
+ * the data, return intermediate results, and then finish consuming the data
+ * when @aNextState is called.
+ *
+ * It's also possible to yield during an unbuffered read. Just return a
+ * Transition::ContinueUnbufferedAfterYield(). Just like with
+ * Transition::ContinueUnbuffered(), the @aUnbufferedState must be the same as
+ * the one originally passed to Transition::ToUnbuffered(). The second argument,
+ * @aSize, specifies the amount of data that the lexer has already consumed.
+ * When @aUnbufferedState is next invoked, it will get the same data that it
+ * received previously, except that the first @aSize bytes will be excluded.
+ * This makes it easy to consume unbuffered data incrementally.
+ *
+ * XXX(seth): We should be able to get of the |State| stuff totally once bug
+ * 1198451 lands, since we can then just return a function representing the next
+ * state directly.
+ */
+template <typename State, size_t InlineBufferSize = 16>
+class StreamingLexer {
+ public:
+ StreamingLexer(const LexerTransition<State>& aStartState,
+ const LexerTransition<State>& aTruncatedState)
+ : mTransition(TerminalState::FAILURE),
+ mTruncatedTransition(aTruncatedState) {
+ if (!aStartState.NextStateIsTerminal() &&
+ aStartState.ControlFlow() == ControlFlowStrategy::YIELD) {
+ // Allowing a StreamingLexer to start in a yield state doesn't make sense
+ // semantically (since yield states are supposed to deliver the same data
+ // as previous states, and there's no previous state here), but more
+ // importantly, it's necessary to advance a SourceBufferIterator at least
+ // once before you can read from it, and adding the necessary checks to
+ // Lex() to avoid that issue has the potential to mask real bugs. So
+ // instead, it's better to forbid starting in a yield state.
+ MOZ_ASSERT_UNREACHABLE("Starting in a yield state");
+ return;
+ }
+
+ if (!aTruncatedState.NextStateIsTerminal() &&
+ (aTruncatedState.ControlFlow() == ControlFlowStrategy::YIELD ||
+ aTruncatedState.Buffering() == BufferingStrategy::UNBUFFERED ||
+ aTruncatedState.Size() != 0)) {
+ // The truncated state can't receive any data because, by definition,
+ // there is no more data to receive. That means that yielding or an
+ // unbuffered read would not make sense, and that the state must require
+ // zero bytes.
+ MOZ_ASSERT_UNREACHABLE("Truncated state makes no sense");
+ return;
+ }
+
+ SetTransition(aStartState);
+ }
+
+ /**
+ * From the given SourceBufferIterator, aIterator, create a new iterator at
+ * the same position, with the given read limit, aReadLimit. The read limit
+ * applies after adjusting for the position. If the given iterator has been
+ * advanced, but required buffering inside StreamingLexer, the position
+ * of the cloned iterator will be at the beginning of buffered data; this
+ * should match the perspective of the caller.
+ */
+ Maybe<SourceBufferIterator> Clone(SourceBufferIterator& aIterator,
+ size_t aReadLimit) const {
+ // In order to advance to the current position of the iterator from the
+ // perspective of the caller, we need to take into account if we are
+ // buffering data.
+ size_t pos = aIterator.Position();
+ if (!mBuffer.empty()) {
+ pos += aIterator.Length();
+ MOZ_ASSERT(pos > mBuffer.length());
+ pos -= mBuffer.length();
+ }
+
+ size_t readLimit = aReadLimit;
+ if (aReadLimit != SIZE_MAX) {
+ readLimit += pos;
+ }
+
+ SourceBufferIterator other = aIterator.Owner()->Iterator(readLimit);
+
+ // Since the current iterator has already advanced to this point, we
+ // know that the state can only be READY or COMPLETE. That does not mean
+ // everything is stored in a single chunk, and may require multiple Advance
+ // calls to get where we want to be.
+ SourceBufferIterator::State state;
+ do {
+ state = other.Advance(pos);
+ if (state != SourceBufferIterator::READY) {
+ // The only way we should fail to advance over data we already seen is
+ // if we hit an error while inserting data into the buffer. This will
+ // cause an early exit.
+ MOZ_ASSERT(NS_FAILED(other.CompletionStatus()));
+ return Nothing();
+ }
+ MOZ_ASSERT(pos >= other.Length());
+ pos -= other.Length();
+ } while (pos > 0);
+
+ // Force the data pointer to be where we expect it to be.
+ state = other.Advance(0);
+ if (state != SourceBufferIterator::READY) {
+ // The current position could be the end of the buffer, in which case
+ // there is no point cloning with no more data to read.
+ MOZ_ASSERT(state == SourceBufferIterator::COMPLETE);
+ return Nothing();
+ }
+ return Some(std::move(other));
+ }
+
+ template <typename Func>
+ LexerResult Lex(SourceBufferIterator& aIterator, IResumable* aOnResume,
+ Func aFunc) {
+ if (mTransition.NextStateIsTerminal()) {
+ // We've already reached a terminal state. We never deliver any more data
+ // in this case; just return the terminal state again immediately.
+ return LexerResult(mTransition.NextStateAsTerminal());
+ }
+
+ Maybe<LexerResult> result;
+
+ // If the lexer requested a yield last time, we deliver the same data again
+ // before we read anything else from |aIterator|. Note that although to the
+ // callers of Lex(), Yield::NEED_MORE_DATA is just another type of yield,
+ // internally they're different in that we don't redeliver the same data in
+ // the Yield::NEED_MORE_DATA case, and |mYieldingToState| is not set. This
+ // means that for Yield::NEED_MORE_DATA, we go directly to the loop below.
+ if (mYieldingToState) {
+ result = mTransition.Buffering() == BufferingStrategy::UNBUFFERED
+ ? UnbufferedReadAfterYield(aIterator, aFunc)
+ : BufferedReadAfterYield(aIterator, aFunc);
+ }
+
+ while (!result) {
+ MOZ_ASSERT_IF(mTransition.Buffering() == BufferingStrategy::UNBUFFERED,
+ mUnbufferedState);
+
+ // Figure out how much we need to read.
+ const size_t toRead =
+ mTransition.Buffering() == BufferingStrategy::UNBUFFERED
+ ? mUnbufferedState->mBytesRemaining
+ : mTransition.Size() - mBuffer.length();
+
+ // Attempt to advance the iterator by |toRead| bytes.
+ switch (aIterator.AdvanceOrScheduleResume(toRead, aOnResume)) {
+ case SourceBufferIterator::WAITING:
+ // We can't continue because the rest of the data hasn't arrived from
+ // the network yet. We don't have to do anything special; the
+ // SourceBufferIterator will ensure that |aOnResume| gets called when
+ // more data is available.
+ result = Some(LexerResult(Yield::NEED_MORE_DATA));
+ break;
+
+ case SourceBufferIterator::COMPLETE:
+ // The data is truncated; if not, the lexer would've reached a
+ // terminal state by now. We only get to
+ // SourceBufferIterator::COMPLETE after every byte of data has been
+ // delivered to the lexer.
+ result = Truncated(aIterator, aFunc);
+ break;
+
+ case SourceBufferIterator::READY:
+ // Process the new data that became available.
+ MOZ_ASSERT(aIterator.Data());
+
+ result = mTransition.Buffering() == BufferingStrategy::UNBUFFERED
+ ? UnbufferedRead(aIterator, aFunc)
+ : BufferedRead(aIterator, aFunc);
+ break;
+
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unknown SourceBufferIterator state");
+ result = SetTransition(Transition::TerminateFailure());
+ }
+ };
+
+ return *result;
+ }
+
+ private:
+ template <typename Func>
+ Maybe<LexerResult> UnbufferedRead(SourceBufferIterator& aIterator,
+ Func aFunc) {
+ MOZ_ASSERT(mTransition.Buffering() == BufferingStrategy::UNBUFFERED);
+ MOZ_ASSERT(mUnbufferedState);
+ MOZ_ASSERT(!mYieldingToState);
+ MOZ_ASSERT(mBuffer.empty(),
+ "Buffered read at the same time as unbuffered read?");
+ MOZ_ASSERT(aIterator.Length() <= mUnbufferedState->mBytesRemaining,
+ "Read too much data during unbuffered read?");
+ MOZ_ASSERT(mUnbufferedState->mBytesConsumedInCurrentChunk == 0,
+ "Already consumed data in the current chunk, but not yielding?");
+
+ if (mUnbufferedState->mBytesRemaining == 0) {
+ // We're done with the unbuffered read, so transition to the next state.
+ return SetTransition(aFunc(mTransition.NextState(), nullptr, 0));
+ }
+
+ return ContinueUnbufferedRead(aIterator.Data(), aIterator.Length(),
+ aIterator.Length(), aFunc);
+ }
+
+ template <typename Func>
+ Maybe<LexerResult> UnbufferedReadAfterYield(SourceBufferIterator& aIterator,
+ Func aFunc) {
+ MOZ_ASSERT(mTransition.Buffering() == BufferingStrategy::UNBUFFERED);
+ MOZ_ASSERT(mUnbufferedState);
+ MOZ_ASSERT(mYieldingToState);
+ MOZ_ASSERT(mBuffer.empty(),
+ "Buffered read at the same time as unbuffered read?");
+ MOZ_ASSERT(aIterator.Length() <= mUnbufferedState->mBytesRemaining,
+ "Read too much data during unbuffered read?");
+ MOZ_ASSERT(
+ mUnbufferedState->mBytesConsumedInCurrentChunk <= aIterator.Length(),
+ "Consumed more data than the current chunk holds?");
+ MOZ_ASSERT(mTransition.UnbufferedState() == *mYieldingToState);
+
+ mYieldingToState = Nothing();
+
+ if (mUnbufferedState->mBytesRemaining == 0) {
+ // We're done with the unbuffered read, so transition to the next state.
+ return SetTransition(aFunc(mTransition.NextState(), nullptr, 0));
+ }
+
+ // Since we've yielded, we may have already consumed some data in this
+ // chunk. Make the necessary adjustments. (Note that the std::min call is
+ // just belt-and-suspenders to keep this code memory safe even if there's
+ // a bug somewhere.)
+ const size_t toSkip = std::min(
+ mUnbufferedState->mBytesConsumedInCurrentChunk, aIterator.Length());
+ const char* data = aIterator.Data() + toSkip;
+ const size_t length = aIterator.Length() - toSkip;
+
+ // If |length| is zero, we've hit the end of the current chunk. This only
+ // happens if we yield right at the end of a chunk. Rather than call |aFunc|
+ // with a |length| of zero bytes (which seems potentially surprising to
+ // decoder authors), we go ahead and read more data.
+ if (length == 0) {
+ return FinishCurrentChunkOfUnbufferedRead(aIterator.Length());
+ }
+
+ return ContinueUnbufferedRead(data, length, aIterator.Length(), aFunc);
+ }
+
+ template <typename Func>
+ Maybe<LexerResult> ContinueUnbufferedRead(const char* aData, size_t aLength,
+ size_t aChunkLength, Func aFunc) {
+ // Call aFunc with the unbuffered state to indicate that we're in the
+ // middle of an unbuffered read. We enforce that any state transition
+ // passed back to us is either a terminal state or takes us back to the
+ // unbuffered state.
+ LexerTransition<State> unbufferedTransition =
+ aFunc(mTransition.UnbufferedState(), aData, aLength);
+
+ // If we reached a terminal state, we're done.
+ if (unbufferedTransition.NextStateIsTerminal()) {
+ return SetTransition(unbufferedTransition);
+ }
+
+ MOZ_ASSERT(mTransition.UnbufferedState() ==
+ unbufferedTransition.NextState());
+
+ // Perform bookkeeping.
+ if (unbufferedTransition.ControlFlow() == ControlFlowStrategy::YIELD) {
+ mUnbufferedState->mBytesConsumedInCurrentChunk +=
+ unbufferedTransition.Size();
+ return SetTransition(unbufferedTransition);
+ }
+
+ MOZ_ASSERT(unbufferedTransition.Size() == 0);
+ return FinishCurrentChunkOfUnbufferedRead(aChunkLength);
+ }
+
+ Maybe<LexerResult> FinishCurrentChunkOfUnbufferedRead(size_t aChunkLength) {
+ // We've finished an unbuffered read of a chunk of length |aChunkLength|, so
+ // update |myBytesRemaining| to reflect that we're |aChunkLength| closer to
+ // the end of the unbuffered read. (The std::min call is just
+ // belt-and-suspenders to keep this code memory safe even if there's a bug
+ // somewhere.)
+ mUnbufferedState->mBytesRemaining -=
+ std::min(mUnbufferedState->mBytesRemaining, aChunkLength);
+
+ // Since we're moving on to a new chunk, we can forget about the count of
+ // bytes consumed by yielding in the current chunk.
+ mUnbufferedState->mBytesConsumedInCurrentChunk = 0;
+
+ return Nothing(); // Keep processing.
+ }
+
+ template <typename Func>
+ Maybe<LexerResult> BufferedRead(SourceBufferIterator& aIterator, Func aFunc) {
+ MOZ_ASSERT(mTransition.Buffering() == BufferingStrategy::BUFFERED);
+ MOZ_ASSERT(!mYieldingToState);
+ MOZ_ASSERT(!mUnbufferedState,
+ "Buffered read at the same time as unbuffered read?");
+ MOZ_ASSERT(mBuffer.length() < mTransition.Size() ||
+ (mBuffer.length() == 0 && mTransition.Size() == 0),
+ "Buffered more than we needed?");
+
+ // If we have all the data, we don't actually need to buffer anything.
+ if (mBuffer.empty() && aIterator.Length() == mTransition.Size()) {
+ return SetTransition(
+ aFunc(mTransition.NextState(), aIterator.Data(), aIterator.Length()));
+ }
+
+ // We do need to buffer, so make sure the buffer has enough capacity. We
+ // deliberately wait until we know for sure we need to buffer to call
+ // reserve() since it could require memory allocation.
+ if (!mBuffer.reserve(mTransition.Size())) {
+ return SetTransition(Transition::TerminateFailure());
+ }
+
+ // Append the new data we just got to the buffer.
+ if (!mBuffer.append(aIterator.Data(), aIterator.Length())) {
+ return SetTransition(Transition::TerminateFailure());
+ }
+
+ if (mBuffer.length() != mTransition.Size()) {
+ return Nothing(); // Keep processing.
+ }
+
+ // We've buffered everything, so transition to the next state.
+ return SetTransition(
+ aFunc(mTransition.NextState(), mBuffer.begin(), mBuffer.length()));
+ }
+
+ template <typename Func>
+ Maybe<LexerResult> BufferedReadAfterYield(SourceBufferIterator& aIterator,
+ Func aFunc) {
+ MOZ_ASSERT(mTransition.Buffering() == BufferingStrategy::BUFFERED);
+ MOZ_ASSERT(mYieldingToState);
+ MOZ_ASSERT(!mUnbufferedState,
+ "Buffered read at the same time as unbuffered read?");
+ MOZ_ASSERT(mBuffer.length() <= mTransition.Size(),
+ "Buffered more than we needed?");
+
+ State nextState = std::move(*mYieldingToState);
+
+ // After a yield, we need to take the same data that we delivered to the
+ // last state, and deliver it again to the new state. We know that this is
+ // happening right at a state transition, and that the last state was a
+ // buffered read, so there are two cases:
+
+ // 1. We got the data from the SourceBufferIterator directly.
+ if (mBuffer.empty() && aIterator.Length() == mTransition.Size()) {
+ return SetTransition(
+ aFunc(nextState, aIterator.Data(), aIterator.Length()));
+ }
+
+ // 2. We got the data from the buffer.
+ if (mBuffer.length() == mTransition.Size()) {
+ return SetTransition(aFunc(nextState, mBuffer.begin(), mBuffer.length()));
+ }
+
+ // Anything else indicates a bug.
+ MOZ_ASSERT_UNREACHABLE("Unexpected state encountered during yield");
+ return SetTransition(Transition::TerminateFailure());
+ }
+
+ template <typename Func>
+ Maybe<LexerResult> Truncated(SourceBufferIterator& aIterator, Func aFunc) {
+ // The data is truncated. Let the lexer clean up and decide which terminal
+ // state we should end up in.
+ LexerTransition<State> transition =
+ mTruncatedTransition.NextStateIsTerminal()
+ ? mTruncatedTransition
+ : aFunc(mTruncatedTransition.NextState(), nullptr, 0);
+
+ if (!transition.NextStateIsTerminal()) {
+ MOZ_ASSERT_UNREACHABLE("Truncated state didn't lead to terminal state?");
+ return SetTransition(Transition::TerminateFailure());
+ }
+
+ // If the SourceBuffer was completed with a failing state, we end in
+ // TerminalState::FAILURE no matter what. This only happens in exceptional
+ // situations like SourceBuffer itself encountering a failure due to OOM.
+ if (NS_FAILED(aIterator.CompletionStatus())) {
+ return SetTransition(Transition::TerminateFailure());
+ }
+
+ return SetTransition(transition);
+ }
+
+ Maybe<LexerResult> SetTransition(const LexerTransition<State>& aTransition) {
+ // There should be no transitions while we're buffering for a buffered read
+ // unless they're to terminal states. (The terminal state transitions would
+ // generally be triggered by error handling code.)
+ MOZ_ASSERT_IF(!mBuffer.empty(), aTransition.NextStateIsTerminal() ||
+ mBuffer.length() == mTransition.Size());
+
+ // Similarly, the only transitions allowed in the middle of an unbuffered
+ // read are to a terminal state, or a yield to the same state. Otherwise, we
+ // should remain in the same state until the unbuffered read completes.
+ MOZ_ASSERT_IF(
+ mUnbufferedState,
+ aTransition.NextStateIsTerminal() ||
+ (aTransition.ControlFlow() == ControlFlowStrategy::YIELD &&
+ aTransition.NextState() == mTransition.UnbufferedState()) ||
+ mUnbufferedState->mBytesRemaining == 0);
+
+ // If this transition is a yield, save the next state and return. We'll
+ // handle the rest when Lex() gets called again.
+ if (!aTransition.NextStateIsTerminal() &&
+ aTransition.ControlFlow() == ControlFlowStrategy::YIELD) {
+ mYieldingToState = Some(aTransition.NextState());
+ return Some(LexerResult(Yield::OUTPUT_AVAILABLE));
+ }
+
+ // Update our transition.
+ mTransition = aTransition;
+
+ // Get rid of anything left over from the previous state.
+ mBuffer.clear();
+ mYieldingToState = Nothing();
+ mUnbufferedState = Nothing();
+
+ // If we reached a terminal state, let the caller know.
+ if (mTransition.NextStateIsTerminal()) {
+ return Some(LexerResult(mTransition.NextStateAsTerminal()));
+ }
+
+ // If we're entering an unbuffered state, record how long we'll stay in it.
+ if (mTransition.Buffering() == BufferingStrategy::UNBUFFERED) {
+ mUnbufferedState.emplace(mTransition.Size());
+ }
+
+ return Nothing(); // Keep processing.
+ }
+
+ // State that tracks our position within an unbuffered read.
+ struct UnbufferedState {
+ explicit UnbufferedState(size_t aBytesRemaining)
+ : mBytesRemaining(aBytesRemaining), mBytesConsumedInCurrentChunk(0) {}
+
+ size_t mBytesRemaining;
+ size_t mBytesConsumedInCurrentChunk;
+ };
+
+ Vector<char, InlineBufferSize> mBuffer;
+ LexerTransition<State> mTransition;
+ const LexerTransition<State> mTruncatedTransition;
+ Maybe<State> mYieldingToState;
+ Maybe<UnbufferedState> mUnbufferedState;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_StreamingLexer_h
diff --git a/image/SurfaceCache.cpp b/image/SurfaceCache.cpp
new file mode 100644
index 0000000000..a514f41b7c
--- /dev/null
+++ b/image/SurfaceCache.cpp
@@ -0,0 +1,1970 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * SurfaceCache is a service for caching temporary surfaces in imagelib.
+ */
+
+#include "SurfaceCache.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "ISurfaceProvider.h"
+#include "Image.h"
+#include "LookupResult.h"
+#include "ShutdownTracker.h"
+#include "gfx2DGlue.h"
+#include "gfxPlatform.h"
+#include "imgFrame.h"
+#include "mozilla/AppShutdown.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/CheckedInt.h"
+#include "mozilla/DebugOnly.h"
+#include "mozilla/Likely.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/StaticMutex.h"
+#include "mozilla/StaticPrefs_image.h"
+#include "mozilla/StaticPtr.h"
+
+#include "nsExpirationTracker.h"
+#include "nsHashKeys.h"
+#include "nsIMemoryReporter.h"
+#include "nsRefPtrHashtable.h"
+#include "nsSize.h"
+#include "nsTArray.h"
+#include "Orientation.h"
+#include "prsystem.h"
+
+using std::max;
+using std::min;
+
+namespace mozilla {
+
+using namespace gfx;
+
+namespace image {
+
+MOZ_DEFINE_MALLOC_SIZE_OF(SurfaceCacheMallocSizeOf)
+
+class CachedSurface;
+class SurfaceCacheImpl;
+
+///////////////////////////////////////////////////////////////////////////////
+// Static Data
+///////////////////////////////////////////////////////////////////////////////
+
+// The single surface cache instance.
+static StaticRefPtr<SurfaceCacheImpl> sInstance;
+
+// The mutex protecting the surface cache.
+static StaticMutex sInstanceMutex MOZ_UNANNOTATED;
+
+///////////////////////////////////////////////////////////////////////////////
+// SurfaceCache Implementation
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Cost models the cost of storing a surface in the cache. Right now, this is
+ * simply an estimate of the size of the surface in bytes, but in the future it
+ * may be worth taking into account the cost of rematerializing the surface as
+ * well.
+ */
+typedef size_t Cost;
+
+static Cost ComputeCost(const IntSize& aSize, uint32_t aBytesPerPixel) {
+ MOZ_ASSERT(aBytesPerPixel == 1 || aBytesPerPixel == 4);
+ return aSize.width * aSize.height * aBytesPerPixel;
+}
+
+/**
+ * Since we want to be able to make eviction decisions based on cost, we need to
+ * be able to look up the CachedSurface which has a certain cost as well as the
+ * cost associated with a certain CachedSurface. To make this possible, in data
+ * structures we actually store a CostEntry, which contains a weak pointer to
+ * its associated surface.
+ *
+ * To make usage of the weak pointer safe, SurfaceCacheImpl always calls
+ * StartTracking after a surface is stored in the cache and StopTracking before
+ * it is removed.
+ */
+class CostEntry {
+ public:
+ CostEntry(NotNull<CachedSurface*> aSurface, Cost aCost)
+ : mSurface(aSurface), mCost(aCost) {}
+
+ NotNull<CachedSurface*> Surface() const { return mSurface; }
+ Cost GetCost() const { return mCost; }
+
+ bool operator==(const CostEntry& aOther) const {
+ return mSurface == aOther.mSurface && mCost == aOther.mCost;
+ }
+
+ bool operator<(const CostEntry& aOther) const {
+ return mCost < aOther.mCost ||
+ (mCost == aOther.mCost && mSurface < aOther.mSurface);
+ }
+
+ private:
+ NotNull<CachedSurface*> mSurface;
+ Cost mCost;
+};
+
+/**
+ * A CachedSurface associates a surface with a key that uniquely identifies that
+ * surface.
+ */
+class CachedSurface {
+ ~CachedSurface() {}
+
+ public:
+ MOZ_DECLARE_REFCOUNTED_TYPENAME(CachedSurface)
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CachedSurface)
+
+ explicit CachedSurface(NotNull<ISurfaceProvider*> aProvider)
+ : mProvider(aProvider), mIsLocked(false) {}
+
+ DrawableSurface GetDrawableSurface() const {
+ if (MOZ_UNLIKELY(IsPlaceholder())) {
+ MOZ_ASSERT_UNREACHABLE("Called GetDrawableSurface() on a placeholder");
+ return DrawableSurface();
+ }
+
+ return mProvider->Surface();
+ }
+
+ DrawableSurface GetDrawableSurfaceEvenIfPlaceholder() const {
+ return mProvider->Surface();
+ }
+
+ void SetLocked(bool aLocked) {
+ if (IsPlaceholder()) {
+ return; // Can't lock a placeholder.
+ }
+
+ // Update both our state and our provider's state. Some surface providers
+ // are permanently locked; maintaining our own locking state enables us to
+ // respect SetLocked() even when it's meaningless from the provider's
+ // perspective.
+ mIsLocked = aLocked;
+ mProvider->SetLocked(aLocked);
+ }
+
+ bool IsLocked() const {
+ return !IsPlaceholder() && mIsLocked && mProvider->IsLocked();
+ }
+
+ void SetCannotSubstitute() {
+ mProvider->Availability().SetCannotSubstitute();
+ }
+ bool CannotSubstitute() const {
+ return mProvider->Availability().CannotSubstitute();
+ }
+
+ bool IsPlaceholder() const {
+ return mProvider->Availability().IsPlaceholder();
+ }
+ bool IsDecoded() const { return !IsPlaceholder() && mProvider->IsFinished(); }
+
+ ImageKey GetImageKey() const { return mProvider->GetImageKey(); }
+ const SurfaceKey& GetSurfaceKey() const { return mProvider->GetSurfaceKey(); }
+ nsExpirationState* GetExpirationState() { return &mExpirationState; }
+
+ CostEntry GetCostEntry() {
+ return image::CostEntry(WrapNotNull(this), mProvider->LogicalSizeInBytes());
+ }
+
+ size_t ShallowSizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
+ return aMallocSizeOf(this) + aMallocSizeOf(mProvider.get());
+ }
+
+ void InvalidateRecording() { mProvider->InvalidateRecording(); }
+
+ // A helper type used by SurfaceCacheImpl::CollectSizeOfSurfaces.
+ struct MOZ_STACK_CLASS SurfaceMemoryReport {
+ SurfaceMemoryReport(nsTArray<SurfaceMemoryCounter>& aCounters,
+ MallocSizeOf aMallocSizeOf)
+ : mCounters(aCounters), mMallocSizeOf(aMallocSizeOf) {}
+
+ void Add(NotNull<CachedSurface*> aCachedSurface, bool aIsFactor2) {
+ if (aCachedSurface->IsPlaceholder()) {
+ return;
+ }
+
+ // Record the memory used by the ISurfaceProvider. This may not have a
+ // straightforward relationship to the size of the surface that
+ // DrawableRef() returns if the surface is generated dynamically. (i.e.,
+ // for surfaces with PlaybackType::eAnimated.)
+ aCachedSurface->mProvider->AddSizeOfExcludingThis(
+ mMallocSizeOf, [&](ISurfaceProvider::AddSizeOfCbData& aMetadata) {
+ SurfaceMemoryCounter counter(aCachedSurface->GetSurfaceKey(),
+ aCachedSurface->IsLocked(),
+ aCachedSurface->CannotSubstitute(),
+ aIsFactor2, aMetadata.mFinished);
+
+ counter.Values().SetDecodedHeap(aMetadata.mHeapBytes);
+ counter.Values().SetDecodedNonHeap(aMetadata.mNonHeapBytes);
+ counter.Values().SetDecodedUnknown(aMetadata.mUnknownBytes);
+ counter.Values().SetExternalHandles(aMetadata.mExternalHandles);
+ counter.Values().SetFrameIndex(aMetadata.mIndex);
+ counter.Values().SetExternalId(aMetadata.mExternalId);
+ counter.Values().SetSurfaceTypes(aMetadata.mTypes);
+
+ mCounters.AppendElement(counter);
+ });
+ }
+
+ private:
+ nsTArray<SurfaceMemoryCounter>& mCounters;
+ MallocSizeOf mMallocSizeOf;
+ };
+
+ private:
+ nsExpirationState mExpirationState;
+ NotNull<RefPtr<ISurfaceProvider>> mProvider;
+ bool mIsLocked;
+};
+
+static int64_t AreaOfIntSize(const IntSize& aSize) {
+ return static_cast<int64_t>(aSize.width) * static_cast<int64_t>(aSize.height);
+}
+
+/**
+ * An ImageSurfaceCache is a per-image surface cache. For correctness we must be
+ * able to remove all surfaces associated with an image when the image is
+ * destroyed or invalidated. Since this will happen frequently, it makes sense
+ * to make it cheap by storing the surfaces for each image separately.
+ *
+ * ImageSurfaceCache also keeps track of whether its associated image is locked
+ * or unlocked.
+ *
+ * The cache may also enter "factor of 2" mode which occurs when the number of
+ * surfaces in the cache exceeds the "image.cache.factor2.threshold-surfaces"
+ * pref plus the number of native sizes of the image. When in "factor of 2"
+ * mode, the cache will strongly favour sizes which are a factor of 2 of the
+ * largest native size. It accomplishes this by suggesting a factor of 2 size
+ * when lookups fail and substituting the nearest factor of 2 surface to the
+ * ideal size as the "best" available (as opposed to substitution but not
+ * found). This allows us to minimize memory consumption and CPU time spent
+ * decoding when a website requires many variants of the same surface.
+ */
+class ImageSurfaceCache {
+ ~ImageSurfaceCache() {}
+
+ public:
+ explicit ImageSurfaceCache(const ImageKey aImageKey)
+ : mLocked(false),
+ mFactor2Mode(false),
+ mFactor2Pruned(false),
+ mIsVectorImage(aImageKey->GetType() == imgIContainer::TYPE_VECTOR) {}
+
+ MOZ_DECLARE_REFCOUNTED_TYPENAME(ImageSurfaceCache)
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageSurfaceCache)
+
+ typedef nsRefPtrHashtable<nsGenericHashKey<SurfaceKey>, CachedSurface>
+ SurfaceTable;
+
+ auto Values() const { return mSurfaces.Values(); }
+ uint32_t Count() const { return mSurfaces.Count(); }
+ bool IsEmpty() const { return mSurfaces.Count() == 0; }
+
+ size_t ShallowSizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
+ size_t bytes = aMallocSizeOf(this) +
+ mSurfaces.ShallowSizeOfExcludingThis(aMallocSizeOf);
+ for (const auto& value : Values()) {
+ bytes += value->ShallowSizeOfIncludingThis(aMallocSizeOf);
+ }
+ return bytes;
+ }
+
+ [[nodiscard]] bool Insert(NotNull<CachedSurface*> aSurface) {
+ MOZ_ASSERT(!mLocked || aSurface->IsPlaceholder() || aSurface->IsLocked(),
+ "Inserting an unlocked surface for a locked image");
+ const auto& surfaceKey = aSurface->GetSurfaceKey();
+ if (surfaceKey.Region()) {
+ // We don't allow substitutes for surfaces with regions, so we don't want
+ // to allow factor of 2 mode pruning to release these surfaces.
+ aSurface->SetCannotSubstitute();
+ }
+ return mSurfaces.InsertOrUpdate(surfaceKey, RefPtr<CachedSurface>{aSurface},
+ fallible);
+ }
+
+ already_AddRefed<CachedSurface> Remove(NotNull<CachedSurface*> aSurface) {
+ MOZ_ASSERT(mSurfaces.GetWeak(aSurface->GetSurfaceKey()),
+ "Should not be removing a surface we don't have");
+
+ RefPtr<CachedSurface> surface;
+ mSurfaces.Remove(aSurface->GetSurfaceKey(), getter_AddRefs(surface));
+ AfterMaybeRemove();
+ return surface.forget();
+ }
+
+ already_AddRefed<CachedSurface> Lookup(const SurfaceKey& aSurfaceKey,
+ bool aForAccess) {
+ RefPtr<CachedSurface> surface;
+ mSurfaces.Get(aSurfaceKey, getter_AddRefs(surface));
+
+ if (aForAccess) {
+ if (surface) {
+ // We don't want to allow factor of 2 mode pruning to release surfaces
+ // for which the callers will accept no substitute.
+ surface->SetCannotSubstitute();
+ } else if (!mFactor2Mode) {
+ // If no exact match is found, and this is for use rather than internal
+ // accounting (i.e. insert and removal), we know this will trigger a
+ // decode. Make sure we switch now to factor of 2 mode if necessary.
+ MaybeSetFactor2Mode();
+ }
+ }
+
+ return surface.forget();
+ }
+
+ /**
+ * @returns A tuple containing the best matching CachedSurface if available,
+ * a MatchType describing how the CachedSurface was selected, and
+ * an IntSize which is the size the caller should choose to decode
+ * at should it attempt to do so.
+ */
+ std::tuple<already_AddRefed<CachedSurface>, MatchType, IntSize>
+ LookupBestMatch(const SurfaceKey& aIdealKey) {
+ // Try for an exact match first.
+ RefPtr<CachedSurface> exactMatch;
+ mSurfaces.Get(aIdealKey, getter_AddRefs(exactMatch));
+ if (exactMatch) {
+ if (exactMatch->IsDecoded()) {
+ return std::make_tuple(exactMatch.forget(), MatchType::EXACT,
+ IntSize());
+ }
+ } else if (aIdealKey.Region()) {
+ // We cannot substitute if we have a region. Allow it to create an exact
+ // match.
+ return std::make_tuple(exactMatch.forget(), MatchType::NOT_FOUND,
+ IntSize());
+ } else if (!mFactor2Mode) {
+ // If no exact match is found, and we are not in factor of 2 mode, then
+ // we know that we will trigger a decode because at best we will provide
+ // a substitute. Make sure we switch now to factor of 2 mode if necessary.
+ MaybeSetFactor2Mode();
+ }
+
+ // Try for a best match second, if using compact.
+ IntSize suggestedSize = SuggestedSize(aIdealKey.Size());
+ if (suggestedSize != aIdealKey.Size()) {
+ if (!exactMatch) {
+ SurfaceKey compactKey = aIdealKey.CloneWithSize(suggestedSize);
+ mSurfaces.Get(compactKey, getter_AddRefs(exactMatch));
+ if (exactMatch && exactMatch->IsDecoded()) {
+ MOZ_ASSERT(suggestedSize != aIdealKey.Size());
+ return std::make_tuple(exactMatch.forget(),
+ MatchType::SUBSTITUTE_BECAUSE_BEST,
+ suggestedSize);
+ }
+ }
+ }
+
+ // There's no perfect match, so find the best match we can.
+ RefPtr<CachedSurface> bestMatch;
+ for (const auto& value : Values()) {
+ NotNull<CachedSurface*> current = WrapNotNull(value);
+ const SurfaceKey& currentKey = current->GetSurfaceKey();
+
+ // We never match a placeholder or a surface with a region.
+ if (current->IsPlaceholder() || currentKey.Region()) {
+ continue;
+ }
+ // Matching the playback type and SVG context is required.
+ if (currentKey.Playback() != aIdealKey.Playback() ||
+ currentKey.SVGContext() != aIdealKey.SVGContext()) {
+ continue;
+ }
+ // Matching the flags is required.
+ if (currentKey.Flags() != aIdealKey.Flags()) {
+ continue;
+ }
+ // Anything is better than nothing! (Within the constraints we just
+ // checked, of course.)
+ if (!bestMatch) {
+ bestMatch = current;
+ continue;
+ }
+
+ MOZ_ASSERT(bestMatch, "Should have a current best match");
+
+ // Always prefer completely decoded surfaces.
+ bool bestMatchIsDecoded = bestMatch->IsDecoded();
+ if (bestMatchIsDecoded && !current->IsDecoded()) {
+ continue;
+ }
+ if (!bestMatchIsDecoded && current->IsDecoded()) {
+ bestMatch = current;
+ continue;
+ }
+
+ SurfaceKey bestMatchKey = bestMatch->GetSurfaceKey();
+ if (CompareArea(aIdealKey.Size(), bestMatchKey.Size(),
+ currentKey.Size())) {
+ bestMatch = current;
+ }
+ }
+
+ MatchType matchType;
+ if (bestMatch) {
+ if (!exactMatch) {
+ // No exact match, neither ideal nor factor of 2.
+ MOZ_ASSERT(suggestedSize != bestMatch->GetSurfaceKey().Size(),
+ "No exact match despite the fact the sizes match!");
+ matchType = MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND;
+ } else if (exactMatch != bestMatch) {
+ // The exact match is still decoding, but we found a substitute.
+ matchType = MatchType::SUBSTITUTE_BECAUSE_PENDING;
+ } else if (aIdealKey.Size() != bestMatch->GetSurfaceKey().Size()) {
+ // The best factor of 2 match is still decoding, but the best we've got.
+ MOZ_ASSERT(suggestedSize != aIdealKey.Size());
+ MOZ_ASSERT(mFactor2Mode || mIsVectorImage);
+ matchType = MatchType::SUBSTITUTE_BECAUSE_BEST;
+ } else {
+ // The exact match is still decoding, but it's the best we've got.
+ matchType = MatchType::EXACT;
+ }
+ } else {
+ if (exactMatch) {
+ // We found an "exact match"; it must have been a placeholder.
+ MOZ_ASSERT(exactMatch->IsPlaceholder());
+ matchType = MatchType::PENDING;
+ } else {
+ // We couldn't find an exact match *or* a substitute.
+ matchType = MatchType::NOT_FOUND;
+ }
+ }
+
+ return std::make_tuple(bestMatch.forget(), matchType, suggestedSize);
+ }
+
+ void MaybeSetFactor2Mode() {
+ MOZ_ASSERT(!mFactor2Mode);
+
+ // Typically an image cache will not have too many size-varying surfaces, so
+ // if we exceed the given threshold, we should consider using a subset.
+ int32_t thresholdSurfaces =
+ StaticPrefs::image_cache_factor2_threshold_surfaces();
+ if (thresholdSurfaces < 0 ||
+ mSurfaces.Count() <= static_cast<uint32_t>(thresholdSurfaces)) {
+ return;
+ }
+
+ // Determine how many native surfaces this image has. If it is zero, and it
+ // is a vector image, then we should impute a single native size. Otherwise,
+ // it may be zero because we don't know yet, or the image has an error, or
+ // it isn't supported.
+ NotNull<CachedSurface*> current =
+ WrapNotNull(mSurfaces.ConstIter().UserData());
+ Image* image = static_cast<Image*>(current->GetImageKey());
+ size_t nativeSizes = image->GetNativeSizesLength();
+ if (mIsVectorImage) {
+ MOZ_ASSERT(nativeSizes == 0);
+ nativeSizes = 1;
+ } else if (nativeSizes == 0) {
+ return;
+ }
+
+ // Increase the threshold by the number of native sizes. This ensures that
+ // we do not prevent decoding of the image at all its native sizes. It does
+ // not guarantee we will provide a surface at that size however (i.e. many
+ // other sized surfaces are requested, in addition to the native sizes).
+ thresholdSurfaces += nativeSizes;
+ if (mSurfaces.Count() <= static_cast<uint32_t>(thresholdSurfaces)) {
+ return;
+ }
+
+ // We have a valid size, we can change modes.
+ mFactor2Mode = true;
+ }
+
+ template <typename Function>
+ void Prune(Function&& aRemoveCallback) {
+ if (!mFactor2Mode || mFactor2Pruned) {
+ return;
+ }
+
+ // Attempt to discard any surfaces which are not factor of 2 and the best
+ // factor of 2 match exists.
+ bool hasNotFactorSize = false;
+ for (auto iter = mSurfaces.Iter(); !iter.Done(); iter.Next()) {
+ NotNull<CachedSurface*> current = WrapNotNull(iter.UserData());
+ const SurfaceKey& currentKey = current->GetSurfaceKey();
+ const IntSize& currentSize = currentKey.Size();
+
+ // First we check if someone requested this size and would not accept
+ // an alternatively sized surface.
+ if (current->CannotSubstitute()) {
+ continue;
+ }
+
+ // Next we find the best factor of 2 size for this surface. If this
+ // surface is a factor of 2 size, then we want to keep it.
+ IntSize bestSize = SuggestedSize(currentSize);
+ if (bestSize == currentSize) {
+ continue;
+ }
+
+ // Check the cache for a surface with the same parameters except for the
+ // size which uses the closest factor of 2 size.
+ SurfaceKey compactKey = currentKey.CloneWithSize(bestSize);
+ RefPtr<CachedSurface> compactMatch;
+ mSurfaces.Get(compactKey, getter_AddRefs(compactMatch));
+ if (compactMatch && compactMatch->IsDecoded()) {
+ aRemoveCallback(current);
+ iter.Remove();
+ } else {
+ hasNotFactorSize = true;
+ }
+ }
+
+ // We have no surfaces that are not factor of 2 sized, so we can stop
+ // pruning henceforth, because we avoid the insertion of new surfaces that
+ // don't match our sizing set (unless the caller won't accept a
+ // substitution.)
+ if (!hasNotFactorSize) {
+ mFactor2Pruned = true;
+ }
+
+ // We should never leave factor of 2 mode due to pruning in of itself, but
+ // if we discarded surfaces due to the volatile buffers getting released,
+ // it is possible.
+ AfterMaybeRemove();
+ }
+
+ template <typename Function>
+ bool Invalidate(Function&& aRemoveCallback) {
+ // Remove all non-blob recordings from the cache. Invalidate any blob
+ // recordings.
+ bool foundRecording = false;
+ for (auto iter = mSurfaces.Iter(); !iter.Done(); iter.Next()) {
+ NotNull<CachedSurface*> current = WrapNotNull(iter.UserData());
+
+ if (current->GetSurfaceKey().Flags() & SurfaceFlags::RECORD_BLOB) {
+ foundRecording = true;
+ current->InvalidateRecording();
+ continue;
+ }
+
+ aRemoveCallback(current);
+ iter.Remove();
+ }
+
+ AfterMaybeRemove();
+ return foundRecording;
+ }
+
+ IntSize SuggestedSize(const IntSize& aSize) const {
+ IntSize suggestedSize = SuggestedSizeInternal(aSize);
+ if (mIsVectorImage) {
+ suggestedSize = SurfaceCache::ClampVectorSize(suggestedSize);
+ }
+ return suggestedSize;
+ }
+
+ IntSize SuggestedSizeInternal(const IntSize& aSize) const {
+ // When not in factor of 2 mode, we can always decode at the given size.
+ if (!mFactor2Mode) {
+ return aSize;
+ }
+
+ // We cannot enter factor of 2 mode unless we have a minimum number of
+ // surfaces, and we should have left it if the cache was emptied.
+ if (MOZ_UNLIKELY(IsEmpty())) {
+ MOZ_ASSERT_UNREACHABLE("Should not be empty and in factor of 2 mode!");
+ return aSize;
+ }
+
+ // This bit of awkwardness gets the largest native size of the image.
+ NotNull<CachedSurface*> firstSurface =
+ WrapNotNull(mSurfaces.ConstIter().UserData());
+ Image* image = static_cast<Image*>(firstSurface->GetImageKey());
+ IntSize factorSize;
+ if (NS_FAILED(image->GetWidth(&factorSize.width)) ||
+ NS_FAILED(image->GetHeight(&factorSize.height)) ||
+ factorSize.IsEmpty()) {
+ // Valid vector images may have a default size of 0x0. In that case, just
+ // assume a default size of 100x100 and apply the intrinsic ratio if
+ // available. If our guess was too small, don't use factor-of-scaling.
+ MOZ_ASSERT(mIsVectorImage);
+ factorSize = IntSize(100, 100);
+ Maybe<AspectRatio> aspectRatio = image->GetIntrinsicRatio();
+ if (aspectRatio && *aspectRatio) {
+ factorSize.width =
+ NSToIntRound(aspectRatio->ApplyToFloat(float(factorSize.height)));
+ if (factorSize.IsEmpty()) {
+ return aSize;
+ }
+ }
+ }
+
+ if (mIsVectorImage) {
+ // Ensure the aspect ratio matches the native size before forcing the
+ // caller to accept a factor of 2 size. The difference between the aspect
+ // ratios is:
+ //
+ // delta = nativeWidth/nativeHeight - desiredWidth/desiredHeight
+ //
+ // delta*nativeHeight*desiredHeight = nativeWidth*desiredHeight
+ // - desiredWidth*nativeHeight
+ //
+ // Using the maximum accepted delta as a constant, we can avoid the
+ // floating point division and just compare after some integer ops.
+ int32_t delta =
+ factorSize.width * aSize.height - aSize.width * factorSize.height;
+ int32_t maxDelta = (factorSize.height * aSize.height) >> 4;
+ if (delta > maxDelta || delta < -maxDelta) {
+ return aSize;
+ }
+
+ // If the requested size is bigger than the native size, we actually need
+ // to grow the native size instead of shrinking it.
+ if (factorSize.width < aSize.width) {
+ do {
+ IntSize candidate(factorSize.width * 2, factorSize.height * 2);
+ if (!SurfaceCache::IsLegalSize(candidate)) {
+ break;
+ }
+
+ factorSize = candidate;
+ } while (factorSize.width < aSize.width);
+
+ return factorSize;
+ }
+
+ // Otherwise we can find the best fit as normal.
+ }
+
+ // Start with the native size as the best first guess.
+ IntSize bestSize = factorSize;
+ factorSize.width /= 2;
+ factorSize.height /= 2;
+
+ while (!factorSize.IsEmpty()) {
+ if (!CompareArea(aSize, bestSize, factorSize)) {
+ // This size is not better than the last. Since we proceed from largest
+ // to smallest, we know that the next size will not be better if the
+ // previous size was rejected. Break early.
+ break;
+ }
+
+ // The current factor of 2 size is better than the last selected size.
+ bestSize = factorSize;
+ factorSize.width /= 2;
+ factorSize.height /= 2;
+ }
+
+ return bestSize;
+ }
+
+ bool CompareArea(const IntSize& aIdealSize, const IntSize& aBestSize,
+ const IntSize& aSize) const {
+ // Compare sizes. We use an area-based heuristic here instead of computing a
+ // truly optimal answer, since it seems very unlikely to make a difference
+ // for realistic sizes.
+ int64_t idealArea = AreaOfIntSize(aIdealSize);
+ int64_t currentArea = AreaOfIntSize(aSize);
+ int64_t bestMatchArea = AreaOfIntSize(aBestSize);
+
+ // If the best match is smaller than the ideal size, prefer bigger sizes.
+ if (bestMatchArea < idealArea) {
+ if (currentArea > bestMatchArea) {
+ return true;
+ }
+ return false;
+ }
+
+ // Other, prefer sizes closer to the ideal size, but still not smaller.
+ if (idealArea <= currentArea && currentArea < bestMatchArea) {
+ return true;
+ }
+
+ // This surface isn't an improvement over the current best match.
+ return false;
+ }
+
+ template <typename Function>
+ void CollectSizeOfSurfaces(nsTArray<SurfaceMemoryCounter>& aCounters,
+ MallocSizeOf aMallocSizeOf,
+ Function&& aRemoveCallback) {
+ CachedSurface::SurfaceMemoryReport report(aCounters, aMallocSizeOf);
+ for (auto iter = mSurfaces.Iter(); !iter.Done(); iter.Next()) {
+ NotNull<CachedSurface*> surface = WrapNotNull(iter.UserData());
+
+ // We don't need the drawable surface for ourselves, but adding a surface
+ // to the report will trigger this indirectly. If the surface was
+ // discarded by the OS because it was in volatile memory, we should remove
+ // it from the cache immediately rather than include it in the report.
+ DrawableSurface drawableSurface;
+ if (!surface->IsPlaceholder()) {
+ drawableSurface = surface->GetDrawableSurface();
+ if (!drawableSurface) {
+ aRemoveCallback(surface);
+ iter.Remove();
+ continue;
+ }
+ }
+
+ const IntSize& size = surface->GetSurfaceKey().Size();
+ bool factor2Size = false;
+ if (mFactor2Mode) {
+ factor2Size = (size == SuggestedSize(size));
+ }
+ report.Add(surface, factor2Size);
+ }
+
+ AfterMaybeRemove();
+ }
+
+ void SetLocked(bool aLocked) { mLocked = aLocked; }
+ bool IsLocked() const { return mLocked; }
+
+ private:
+ void AfterMaybeRemove() {
+ if (IsEmpty() && mFactor2Mode) {
+ // The last surface for this cache was removed. This can happen if the
+ // surface was stored in a volatile buffer and got purged, or the surface
+ // expired from the cache. If the cache itself lingers for some reason
+ // (e.g. in the process of performing a lookup, the cache itself is
+ // locked), then we need to reset the factor of 2 state because it
+ // requires at least one surface present to get the native size
+ // information from the image.
+ mFactor2Mode = mFactor2Pruned = false;
+ }
+ }
+
+ SurfaceTable mSurfaces;
+
+ bool mLocked;
+
+ // True in "factor of 2" mode.
+ bool mFactor2Mode;
+
+ // True if all non-factor of 2 surfaces have been removed from the cache. Note
+ // that this excludes unsubstitutable sizes.
+ bool mFactor2Pruned;
+
+ // True if the surfaces are produced from a vector image. If so, it must match
+ // the aspect ratio when using factor of 2 mode.
+ bool mIsVectorImage;
+};
+
+/**
+ * SurfaceCacheImpl is responsible for determining which surfaces will be cached
+ * and managing the surface cache data structures. Rather than interact with
+ * SurfaceCacheImpl directly, client code interacts with SurfaceCache, which
+ * maintains high-level invariants and encapsulates the details of the surface
+ * cache's implementation.
+ */
+class SurfaceCacheImpl final : public nsIMemoryReporter {
+ public:
+ NS_DECL_ISUPPORTS
+
+ SurfaceCacheImpl(uint32_t aSurfaceCacheExpirationTimeMS,
+ uint32_t aSurfaceCacheDiscardFactor,
+ uint32_t aSurfaceCacheSize)
+ : mExpirationTracker(aSurfaceCacheExpirationTimeMS),
+ mMemoryPressureObserver(new MemoryPressureObserver),
+ mDiscardFactor(aSurfaceCacheDiscardFactor),
+ mMaxCost(aSurfaceCacheSize),
+ mAvailableCost(aSurfaceCacheSize),
+ mLockedCost(0),
+ mOverflowCount(0),
+ mAlreadyPresentCount(0),
+ mTableFailureCount(0),
+ mTrackingFailureCount(0) {
+ nsCOMPtr<nsIObserverService> os = services::GetObserverService();
+ if (os) {
+ os->AddObserver(mMemoryPressureObserver, "memory-pressure", false);
+ }
+ }
+
+ private:
+ virtual ~SurfaceCacheImpl() {
+ nsCOMPtr<nsIObserverService> os = services::GetObserverService();
+ if (os) {
+ os->RemoveObserver(mMemoryPressureObserver, "memory-pressure");
+ }
+
+ UnregisterWeakMemoryReporter(this);
+ }
+
+ public:
+ void InitMemoryReporter() { RegisterWeakMemoryReporter(this); }
+
+ InsertOutcome Insert(NotNull<ISurfaceProvider*> aProvider, bool aSetAvailable,
+ const StaticMutexAutoLock& aAutoLock) {
+ // If this is a duplicate surface, refuse to replace the original.
+ // XXX(seth): Calling Lookup() and then RemoveEntry() does the lookup
+ // twice. We'll make this more efficient in bug 1185137.
+ LookupResult result =
+ Lookup(aProvider->GetImageKey(), aProvider->GetSurfaceKey(), aAutoLock,
+ /* aMarkUsed = */ false);
+ if (MOZ_UNLIKELY(result)) {
+ mAlreadyPresentCount++;
+ return InsertOutcome::FAILURE_ALREADY_PRESENT;
+ }
+
+ if (result.Type() == MatchType::PENDING) {
+ RemoveEntry(aProvider->GetImageKey(), aProvider->GetSurfaceKey(),
+ aAutoLock);
+ }
+
+ MOZ_ASSERT(result.Type() == MatchType::NOT_FOUND ||
+ result.Type() == MatchType::PENDING,
+ "A LookupResult with no surface should be NOT_FOUND or PENDING");
+
+ // If this is bigger than we can hold after discarding everything we can,
+ // refuse to cache it.
+ Cost cost = aProvider->LogicalSizeInBytes();
+ if (MOZ_UNLIKELY(!CanHoldAfterDiscarding(cost))) {
+ mOverflowCount++;
+ return InsertOutcome::FAILURE;
+ }
+
+ // Remove elements in order of cost until we can fit this in the cache. Note
+ // that locked surfaces aren't in mCosts, so we never remove them here.
+ while (cost > mAvailableCost) {
+ MOZ_ASSERT(!mCosts.IsEmpty(),
+ "Removed everything and it still won't fit");
+ Remove(mCosts.LastElement().Surface(), /* aStopTracking */ true,
+ aAutoLock);
+ }
+
+ // Locate the appropriate per-image cache. If there's not an existing cache
+ // for this image, create it.
+ const ImageKey imageKey = aProvider->GetImageKey();
+ RefPtr<ImageSurfaceCache> cache = GetImageCache(imageKey);
+ if (!cache) {
+ cache = new ImageSurfaceCache(imageKey);
+ if (!mImageCaches.InsertOrUpdate(aProvider->GetImageKey(), RefPtr{cache},
+ fallible)) {
+ mTableFailureCount++;
+ return InsertOutcome::FAILURE;
+ }
+ }
+
+ // If we were asked to mark the cache entry available, do so.
+ if (aSetAvailable) {
+ aProvider->Availability().SetAvailable();
+ }
+
+ auto surface = MakeNotNull<RefPtr<CachedSurface>>(aProvider);
+
+ // We require that locking succeed if the image is locked and we're not
+ // inserting a placeholder; the caller may need to know this to handle
+ // errors correctly.
+ bool mustLock = cache->IsLocked() && !surface->IsPlaceholder();
+ if (mustLock) {
+ surface->SetLocked(true);
+ if (!surface->IsLocked()) {
+ return InsertOutcome::FAILURE;
+ }
+ }
+
+ // Insert.
+ MOZ_ASSERT(cost <= mAvailableCost, "Inserting despite too large a cost");
+ if (!cache->Insert(surface)) {
+ mTableFailureCount++;
+ if (mustLock) {
+ surface->SetLocked(false);
+ }
+ return InsertOutcome::FAILURE;
+ }
+
+ if (MOZ_UNLIKELY(!StartTracking(surface, aAutoLock))) {
+ MOZ_ASSERT(!mustLock);
+ Remove(surface, /* aStopTracking */ false, aAutoLock);
+ return InsertOutcome::FAILURE;
+ }
+
+ return InsertOutcome::SUCCESS;
+ }
+
+ void Remove(NotNull<CachedSurface*> aSurface, bool aStopTracking,
+ const StaticMutexAutoLock& aAutoLock) {
+ ImageKey imageKey = aSurface->GetImageKey();
+
+ RefPtr<ImageSurfaceCache> cache = GetImageCache(imageKey);
+ MOZ_ASSERT(cache, "Shouldn't try to remove a surface with no image cache");
+
+ // If the surface was not a placeholder, tell its image that we discarded
+ // it.
+ if (!aSurface->IsPlaceholder()) {
+ static_cast<Image*>(imageKey)->OnSurfaceDiscarded(
+ aSurface->GetSurfaceKey());
+ }
+
+ // If we failed during StartTracking, we can skip this step.
+ if (aStopTracking) {
+ StopTracking(aSurface, /* aIsTracked */ true, aAutoLock);
+ }
+
+ // Individual surfaces must be freed outside the lock.
+ mCachedSurfacesDiscard.AppendElement(cache->Remove(aSurface));
+
+ MaybeRemoveEmptyCache(imageKey, cache);
+ }
+
+ bool StartTracking(NotNull<CachedSurface*> aSurface,
+ const StaticMutexAutoLock& aAutoLock) {
+ CostEntry costEntry = aSurface->GetCostEntry();
+ MOZ_ASSERT(costEntry.GetCost() <= mAvailableCost,
+ "Cost too large and the caller didn't catch it");
+
+ if (aSurface->IsLocked()) {
+ mLockedCost += costEntry.GetCost();
+ MOZ_ASSERT(mLockedCost <= mMaxCost, "Locked more than we can hold?");
+ } else {
+ if (NS_WARN_IF(!mCosts.InsertElementSorted(costEntry, fallible))) {
+ mTrackingFailureCount++;
+ return false;
+ }
+
+ // This may fail during XPCOM shutdown, so we need to ensure the object is
+ // tracked before calling RemoveObject in StopTracking.
+ nsresult rv = mExpirationTracker.AddObjectLocked(aSurface, aAutoLock);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ DebugOnly<bool> foundInCosts = mCosts.RemoveElementSorted(costEntry);
+ MOZ_ASSERT(foundInCosts, "Lost track of costs for this surface");
+ mTrackingFailureCount++;
+ return false;
+ }
+ }
+
+ mAvailableCost -= costEntry.GetCost();
+ return true;
+ }
+
+ void StopTracking(NotNull<CachedSurface*> aSurface, bool aIsTracked,
+ const StaticMutexAutoLock& aAutoLock) {
+ CostEntry costEntry = aSurface->GetCostEntry();
+
+ if (aSurface->IsLocked()) {
+ MOZ_ASSERT(mLockedCost >= costEntry.GetCost(), "Costs don't balance");
+ mLockedCost -= costEntry.GetCost();
+ // XXX(seth): It'd be nice to use an O(log n) lookup here. This is O(n).
+ MOZ_ASSERT(!mCosts.Contains(costEntry),
+ "Shouldn't have a cost entry for a locked surface");
+ } else {
+ if (MOZ_LIKELY(aSurface->GetExpirationState()->IsTracked())) {
+ MOZ_ASSERT(aIsTracked, "Expiration-tracking a surface unexpectedly!");
+ mExpirationTracker.RemoveObjectLocked(aSurface, aAutoLock);
+ } else {
+ // Our call to AddObject must have failed in StartTracking; most likely
+ // we're in XPCOM shutdown right now.
+ MOZ_ASSERT(!aIsTracked, "Not expiration-tracking an unlocked surface!");
+ }
+
+ DebugOnly<bool> foundInCosts = mCosts.RemoveElementSorted(costEntry);
+ MOZ_ASSERT(foundInCosts, "Lost track of costs for this surface");
+ }
+
+ mAvailableCost += costEntry.GetCost();
+ MOZ_ASSERT(mAvailableCost <= mMaxCost,
+ "More available cost than we started with");
+ }
+
+ LookupResult Lookup(const ImageKey aImageKey, const SurfaceKey& aSurfaceKey,
+ const StaticMutexAutoLock& aAutoLock, bool aMarkUsed) {
+ RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
+ if (!cache) {
+ // No cached surfaces for this image.
+ return LookupResult(MatchType::NOT_FOUND);
+ }
+
+ RefPtr<CachedSurface> surface = cache->Lookup(aSurfaceKey, aMarkUsed);
+ if (!surface) {
+ // Lookup in the per-image cache missed.
+ return LookupResult(MatchType::NOT_FOUND);
+ }
+
+ if (surface->IsPlaceholder()) {
+ return LookupResult(MatchType::PENDING);
+ }
+
+ DrawableSurface drawableSurface = surface->GetDrawableSurface();
+ if (!drawableSurface) {
+ // The surface was released by the operating system. Remove the cache
+ // entry as well.
+ Remove(WrapNotNull(surface), /* aStopTracking */ true, aAutoLock);
+ return LookupResult(MatchType::NOT_FOUND);
+ }
+
+ if (aMarkUsed &&
+ !MarkUsed(WrapNotNull(surface), WrapNotNull(cache), aAutoLock)) {
+ Remove(WrapNotNull(surface), /* aStopTracking */ false, aAutoLock);
+ return LookupResult(MatchType::NOT_FOUND);
+ }
+
+ MOZ_ASSERT(surface->GetSurfaceKey() == aSurfaceKey,
+ "Lookup() not returning an exact match?");
+ return LookupResult(std::move(drawableSurface), MatchType::EXACT);
+ }
+
+ LookupResult LookupBestMatch(const ImageKey aImageKey,
+ const SurfaceKey& aSurfaceKey,
+ const StaticMutexAutoLock& aAutoLock,
+ bool aMarkUsed) {
+ RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
+ if (!cache) {
+ // No cached surfaces for this image.
+ return LookupResult(
+ MatchType::NOT_FOUND,
+ SurfaceCache::ClampSize(aImageKey, aSurfaceKey.Size()));
+ }
+
+ // Repeatedly look up the best match, trying again if the resulting surface
+ // has been freed by the operating system, until we can either lock a
+ // surface for drawing or there are no matching surfaces left.
+ // XXX(seth): This is O(N^2), but N is expected to be very small. If we
+ // encounter a performance problem here we can revisit this.
+
+ RefPtr<CachedSurface> surface;
+ DrawableSurface drawableSurface;
+ MatchType matchType = MatchType::NOT_FOUND;
+ IntSize suggestedSize;
+ while (true) {
+ std::tie(surface, matchType, suggestedSize) =
+ cache->LookupBestMatch(aSurfaceKey);
+
+ if (!surface) {
+ return LookupResult(
+ matchType, suggestedSize); // Lookup in the per-image cache missed.
+ }
+
+ drawableSurface = surface->GetDrawableSurface();
+ if (drawableSurface) {
+ break;
+ }
+
+ // The surface was released by the operating system. Remove the cache
+ // entry as well.
+ Remove(WrapNotNull(surface), /* aStopTracking */ true, aAutoLock);
+ }
+
+ MOZ_ASSERT_IF(matchType == MatchType::EXACT,
+ surface->GetSurfaceKey() == aSurfaceKey);
+ MOZ_ASSERT_IF(
+ matchType == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND ||
+ matchType == MatchType::SUBSTITUTE_BECAUSE_PENDING,
+ surface->GetSurfaceKey().Region() == aSurfaceKey.Region() &&
+ surface->GetSurfaceKey().SVGContext() == aSurfaceKey.SVGContext() &&
+ surface->GetSurfaceKey().Playback() == aSurfaceKey.Playback() &&
+ surface->GetSurfaceKey().Flags() == aSurfaceKey.Flags());
+
+ if (matchType == MatchType::EXACT ||
+ matchType == MatchType::SUBSTITUTE_BECAUSE_BEST) {
+ if (aMarkUsed &&
+ !MarkUsed(WrapNotNull(surface), WrapNotNull(cache), aAutoLock)) {
+ Remove(WrapNotNull(surface), /* aStopTracking */ false, aAutoLock);
+ }
+ }
+
+ return LookupResult(std::move(drawableSurface), matchType, suggestedSize);
+ }
+
+ bool CanHold(const Cost aCost) const { return aCost <= mMaxCost; }
+
+ size_t MaximumCapacity() const { return size_t(mMaxCost); }
+
+ void SurfaceAvailable(NotNull<ISurfaceProvider*> aProvider,
+ const StaticMutexAutoLock& aAutoLock) {
+ if (!aProvider->Availability().IsPlaceholder()) {
+ MOZ_ASSERT_UNREACHABLE("Calling SurfaceAvailable on non-placeholder");
+ return;
+ }
+
+ // Reinsert the provider, requesting that Insert() mark it available. This
+ // may or may not succeed, depending on whether some other decoder has
+ // beaten us to the punch and inserted a non-placeholder version of this
+ // surface first, but it's fine either way.
+ // XXX(seth): This could be implemented more efficiently; we should be able
+ // to just update our data structures without reinserting.
+ Insert(aProvider, /* aSetAvailable = */ true, aAutoLock);
+ }
+
+ void LockImage(const ImageKey aImageKey) {
+ RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
+ if (!cache) {
+ cache = new ImageSurfaceCache(aImageKey);
+ mImageCaches.InsertOrUpdate(aImageKey, RefPtr{cache});
+ }
+
+ cache->SetLocked(true);
+
+ // We don't relock this image's existing surfaces right away; instead, the
+ // image should arrange for Lookup() to touch them if they are still useful.
+ }
+
+ void UnlockImage(const ImageKey aImageKey,
+ const StaticMutexAutoLock& aAutoLock) {
+ RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
+ if (!cache || !cache->IsLocked()) {
+ return; // Already unlocked.
+ }
+
+ cache->SetLocked(false);
+ DoUnlockSurfaces(WrapNotNull(cache), /* aStaticOnly = */ false, aAutoLock);
+ }
+
+ void UnlockEntries(const ImageKey aImageKey,
+ const StaticMutexAutoLock& aAutoLock) {
+ RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
+ if (!cache || !cache->IsLocked()) {
+ return; // Already unlocked.
+ }
+
+ // (Note that we *don't* unlock the per-image cache here; that's the
+ // difference between this and UnlockImage.)
+ DoUnlockSurfaces(WrapNotNull(cache),
+ /* aStaticOnly = */
+ !StaticPrefs::image_mem_animated_discardable_AtStartup(),
+ aAutoLock);
+ }
+
+ already_AddRefed<ImageSurfaceCache> RemoveImage(
+ const ImageKey aImageKey, const StaticMutexAutoLock& aAutoLock) {
+ RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
+ if (!cache) {
+ return nullptr; // No cached surfaces for this image, so nothing to do.
+ }
+
+ // Discard all of the cached surfaces for this image.
+ // XXX(seth): This is O(n^2) since for each item in the cache we are
+ // removing an element from the costs array. Since n is expected to be
+ // small, performance should be good, but if usage patterns change we should
+ // change the data structure used for mCosts.
+ for (const auto& value : cache->Values()) {
+ StopTracking(WrapNotNull(value),
+ /* aIsTracked */ true, aAutoLock);
+ }
+
+ // The per-image cache isn't needed anymore, so remove it as well.
+ // This implicitly unlocks the image if it was locked.
+ mImageCaches.Remove(aImageKey);
+
+ // Since we did not actually remove any of the surfaces from the cache
+ // itself, only stopped tracking them, we should free it outside the lock.
+ return cache.forget();
+ }
+
+ void PruneImage(const ImageKey aImageKey,
+ const StaticMutexAutoLock& aAutoLock) {
+ RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
+ if (!cache) {
+ return; // No cached surfaces for this image, so nothing to do.
+ }
+
+ cache->Prune([this, &aAutoLock](NotNull<CachedSurface*> aSurface) -> void {
+ StopTracking(aSurface, /* aIsTracked */ true, aAutoLock);
+ // Individual surfaces must be freed outside the lock.
+ mCachedSurfacesDiscard.AppendElement(aSurface);
+ });
+
+ MaybeRemoveEmptyCache(aImageKey, cache);
+ }
+
+ bool InvalidateImage(const ImageKey aImageKey,
+ const StaticMutexAutoLock& aAutoLock) {
+ RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
+ if (!cache) {
+ return false; // No cached surfaces for this image, so nothing to do.
+ }
+
+ bool rv = cache->Invalidate(
+ [this, &aAutoLock](NotNull<CachedSurface*> aSurface) -> void {
+ StopTracking(aSurface, /* aIsTracked */ true, aAutoLock);
+ // Individual surfaces must be freed outside the lock.
+ mCachedSurfacesDiscard.AppendElement(aSurface);
+ });
+
+ MaybeRemoveEmptyCache(aImageKey, cache);
+ return rv;
+ }
+
+ void DiscardAll(const StaticMutexAutoLock& aAutoLock) {
+ // Remove in order of cost because mCosts is an array and the other data
+ // structures are all hash tables. Note that locked surfaces are not
+ // removed, since they aren't present in mCosts.
+ while (!mCosts.IsEmpty()) {
+ Remove(mCosts.LastElement().Surface(), /* aStopTracking */ true,
+ aAutoLock);
+ }
+ }
+
+ void DiscardForMemoryPressure(const StaticMutexAutoLock& aAutoLock) {
+ // Compute our discardable cost. Since locked surfaces aren't discardable,
+ // we exclude them.
+ const Cost discardableCost = (mMaxCost - mAvailableCost) - mLockedCost;
+ MOZ_ASSERT(discardableCost <= mMaxCost, "Discardable cost doesn't add up");
+
+ // Our target is to raise our available cost by (1 / mDiscardFactor) of our
+ // discardable cost - in other words, we want to end up with about
+ // (discardableCost / mDiscardFactor) fewer bytes stored in the surface
+ // cache after we're done.
+ const Cost targetCost = mAvailableCost + (discardableCost / mDiscardFactor);
+
+ if (targetCost > mMaxCost - mLockedCost) {
+ MOZ_ASSERT_UNREACHABLE("Target cost is more than we can discard");
+ DiscardAll(aAutoLock);
+ return;
+ }
+
+ // Discard surfaces until we've reduced our cost to our target cost.
+ while (mAvailableCost < targetCost) {
+ MOZ_ASSERT(!mCosts.IsEmpty(), "Removed everything and still not done");
+ Remove(mCosts.LastElement().Surface(), /* aStopTracking */ true,
+ aAutoLock);
+ }
+ }
+
+ void TakeDiscard(nsTArray<RefPtr<CachedSurface>>& aDiscard,
+ const StaticMutexAutoLock& aAutoLock) {
+ MOZ_ASSERT(aDiscard.IsEmpty());
+ aDiscard = std::move(mCachedSurfacesDiscard);
+ }
+
+ already_AddRefed<CachedSurface> GetSurfaceForResetAnimation(
+ const ImageKey aImageKey, const SurfaceKey& aSurfaceKey,
+ const StaticMutexAutoLock& aAutoLock) {
+ RefPtr<CachedSurface> surface;
+
+ RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
+ if (!cache) {
+ // No cached surfaces for this image.
+ return surface.forget();
+ }
+
+ surface = cache->Lookup(aSurfaceKey, /* aForAccess = */ false);
+ return surface.forget();
+ }
+
+ void LockSurface(NotNull<CachedSurface*> aSurface,
+ const StaticMutexAutoLock& aAutoLock) {
+ if (aSurface->IsPlaceholder() || aSurface->IsLocked()) {
+ return;
+ }
+
+ StopTracking(aSurface, /* aIsTracked */ true, aAutoLock);
+
+ // Lock the surface. This can fail.
+ aSurface->SetLocked(true);
+ DebugOnly<bool> tracked = StartTracking(aSurface, aAutoLock);
+ MOZ_ASSERT(tracked);
+ }
+
+ size_t ShallowSizeOfIncludingThis(
+ MallocSizeOf aMallocSizeOf, const StaticMutexAutoLock& aAutoLock) const {
+ size_t bytes =
+ aMallocSizeOf(this) + mCosts.ShallowSizeOfExcludingThis(aMallocSizeOf) +
+ mImageCaches.ShallowSizeOfExcludingThis(aMallocSizeOf) +
+ mCachedSurfacesDiscard.ShallowSizeOfExcludingThis(aMallocSizeOf) +
+ mExpirationTracker.ShallowSizeOfExcludingThis(aMallocSizeOf);
+ for (const auto& data : mImageCaches.Values()) {
+ bytes += data->ShallowSizeOfIncludingThis(aMallocSizeOf);
+ }
+ return bytes;
+ }
+
+ NS_IMETHOD
+ CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData,
+ bool aAnonymize) override {
+ StaticMutexAutoLock lock(sInstanceMutex);
+
+ uint32_t lockedImageCount = 0;
+ uint32_t totalSurfaceCount = 0;
+ uint32_t lockedSurfaceCount = 0;
+ for (const auto& cache : mImageCaches.Values()) {
+ totalSurfaceCount += cache->Count();
+ if (cache->IsLocked()) {
+ ++lockedImageCount;
+ }
+ for (const auto& value : cache->Values()) {
+ if (value->IsLocked()) {
+ ++lockedSurfaceCount;
+ }
+ }
+ }
+
+ // clang-format off
+ // We have explicit memory reporting for the surface cache which is more
+ // accurate than the cost metrics we report here, but these metrics are
+ // still useful to report, since they control the cache's behavior.
+ MOZ_COLLECT_REPORT(
+ "explicit/images/cache/overhead", KIND_HEAP, UNITS_BYTES,
+ ShallowSizeOfIncludingThis(SurfaceCacheMallocSizeOf, lock),
+"Memory used by the surface cache data structures, excluding surface data.");
+
+ MOZ_COLLECT_REPORT(
+ "imagelib-surface-cache-estimated-total",
+ KIND_OTHER, UNITS_BYTES, (mMaxCost - mAvailableCost),
+"Estimated total memory used by the imagelib surface cache.");
+
+ MOZ_COLLECT_REPORT(
+ "imagelib-surface-cache-estimated-locked",
+ KIND_OTHER, UNITS_BYTES, mLockedCost,
+"Estimated memory used by locked surfaces in the imagelib surface cache.");
+
+ MOZ_COLLECT_REPORT(
+ "imagelib-surface-cache-tracked-cost-count",
+ KIND_OTHER, UNITS_COUNT, mCosts.Length(),
+"Total number of surfaces tracked for cost (and expiry) in the imagelib surface cache.");
+
+ MOZ_COLLECT_REPORT(
+ "imagelib-surface-cache-tracked-expiry-count",
+ KIND_OTHER, UNITS_COUNT, mExpirationTracker.Length(lock),
+"Total number of surfaces tracked for expiry (and cost) in the imagelib surface cache.");
+
+ MOZ_COLLECT_REPORT(
+ "imagelib-surface-cache-image-count",
+ KIND_OTHER, UNITS_COUNT, mImageCaches.Count(),
+"Total number of images in the imagelib surface cache.");
+
+ MOZ_COLLECT_REPORT(
+ "imagelib-surface-cache-locked-image-count",
+ KIND_OTHER, UNITS_COUNT, lockedImageCount,
+"Total number of locked images in the imagelib surface cache.");
+
+ MOZ_COLLECT_REPORT(
+ "imagelib-surface-cache-image-surface-count",
+ KIND_OTHER, UNITS_COUNT, totalSurfaceCount,
+"Total number of surfaces in the imagelib surface cache.");
+
+ MOZ_COLLECT_REPORT(
+ "imagelib-surface-cache-locked-surfaces-count",
+ KIND_OTHER, UNITS_COUNT, lockedSurfaceCount,
+"Total number of locked surfaces in the imagelib surface cache.");
+
+ MOZ_COLLECT_REPORT(
+ "imagelib-surface-cache-overflow-count",
+ KIND_OTHER, UNITS_COUNT, mOverflowCount,
+"Count of how many times the surface cache has hit its capacity and been "
+"unable to insert a new surface.");
+
+ MOZ_COLLECT_REPORT(
+ "imagelib-surface-cache-tracking-failure-count",
+ KIND_OTHER, UNITS_COUNT, mTrackingFailureCount,
+"Count of how many times the surface cache has failed to begin tracking a "
+"given surface.");
+
+ MOZ_COLLECT_REPORT(
+ "imagelib-surface-cache-already-present-count",
+ KIND_OTHER, UNITS_COUNT, mAlreadyPresentCount,
+"Count of how many times the surface cache has failed to insert a surface "
+"because it is already present.");
+
+ MOZ_COLLECT_REPORT(
+ "imagelib-surface-cache-table-failure-count",
+ KIND_OTHER, UNITS_COUNT, mTableFailureCount,
+"Count of how many times the surface cache has failed to insert a surface "
+"because a hash table could not accept an entry.");
+ // clang-format on
+
+ return NS_OK;
+ }
+
+ void CollectSizeOfSurfaces(const ImageKey aImageKey,
+ nsTArray<SurfaceMemoryCounter>& aCounters,
+ MallocSizeOf aMallocSizeOf,
+ const StaticMutexAutoLock& aAutoLock) {
+ RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
+ if (!cache) {
+ return; // No surfaces for this image.
+ }
+
+ // Report all surfaces in the per-image cache.
+ cache->CollectSizeOfSurfaces(
+ aCounters, aMallocSizeOf,
+ [this, &aAutoLock](NotNull<CachedSurface*> aSurface) -> void {
+ StopTracking(aSurface, /* aIsTracked */ true, aAutoLock);
+ // Individual surfaces must be freed outside the lock.
+ mCachedSurfacesDiscard.AppendElement(aSurface);
+ });
+
+ MaybeRemoveEmptyCache(aImageKey, cache);
+ }
+
+ void ReleaseImageOnMainThread(already_AddRefed<image::Image>&& aImage,
+ const StaticMutexAutoLock& aAutoLock) {
+ RefPtr<image::Image> image = aImage;
+ if (!image) {
+ return;
+ }
+
+ bool needsDispatch = mReleasingImagesOnMainThread.IsEmpty();
+ mReleasingImagesOnMainThread.AppendElement(image);
+
+ if (!needsDispatch ||
+ AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownFinal)) {
+ // Either there is already a ongoing task for ClearReleasingImages() or
+ // it's too late in shutdown to dispatch.
+ return;
+ }
+
+ NS_DispatchToMainThread(NS_NewRunnableFunction(
+ "SurfaceCacheImpl::ReleaseImageOnMainThread",
+ []() -> void { SurfaceCache::ClearReleasingImages(); }));
+ }
+
+ void TakeReleasingImages(nsTArray<RefPtr<image::Image>>& aImage,
+ const StaticMutexAutoLock& aAutoLock) {
+ MOZ_ASSERT(NS_IsMainThread());
+ aImage.SwapElements(mReleasingImagesOnMainThread);
+ }
+
+ private:
+ already_AddRefed<ImageSurfaceCache> GetImageCache(const ImageKey aImageKey) {
+ RefPtr<ImageSurfaceCache> imageCache;
+ mImageCaches.Get(aImageKey, getter_AddRefs(imageCache));
+ return imageCache.forget();
+ }
+
+ void MaybeRemoveEmptyCache(const ImageKey aImageKey,
+ ImageSurfaceCache* aCache) {
+ // Remove the per-image cache if it's unneeded now. Keep it if the image is
+ // locked, since the per-image cache is where we store that state. Note that
+ // we don't push it into mImageCachesDiscard because all of its surfaces
+ // have been removed, so it is safe to free while holding the lock.
+ if (aCache->IsEmpty() && !aCache->IsLocked()) {
+ mImageCaches.Remove(aImageKey);
+ }
+ }
+
+ // This is similar to CanHold() except that it takes into account the costs of
+ // locked surfaces. It's used internally in Insert(), but it's not exposed
+ // publicly because we permit multithreaded access to the surface cache, which
+ // means that the result would be meaningless: another thread could insert a
+ // surface or lock an image at any time.
+ bool CanHoldAfterDiscarding(const Cost aCost) const {
+ return aCost <= mMaxCost - mLockedCost;
+ }
+
+ bool MarkUsed(NotNull<CachedSurface*> aSurface,
+ NotNull<ImageSurfaceCache*> aCache,
+ const StaticMutexAutoLock& aAutoLock) {
+ if (aCache->IsLocked()) {
+ LockSurface(aSurface, aAutoLock);
+ return true;
+ }
+
+ nsresult rv = mExpirationTracker.MarkUsedLocked(aSurface, aAutoLock);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ // If mark used fails, it is because it failed to reinsert the surface
+ // after removing it from the tracker. Thus we need to update our
+ // own accounting but otherwise expect it to be untracked.
+ StopTracking(aSurface, /* aIsTracked */ false, aAutoLock);
+ return false;
+ }
+ return true;
+ }
+
+ void DoUnlockSurfaces(NotNull<ImageSurfaceCache*> aCache, bool aStaticOnly,
+ const StaticMutexAutoLock& aAutoLock) {
+ AutoTArray<NotNull<CachedSurface*>, 8> discard;
+
+ // Unlock all the surfaces the per-image cache is holding.
+ for (const auto& value : aCache->Values()) {
+ NotNull<CachedSurface*> surface = WrapNotNull(value);
+ if (surface->IsPlaceholder() || !surface->IsLocked()) {
+ continue;
+ }
+ if (aStaticOnly &&
+ surface->GetSurfaceKey().Playback() != PlaybackType::eStatic) {
+ continue;
+ }
+ StopTracking(surface, /* aIsTracked */ true, aAutoLock);
+ surface->SetLocked(false);
+ if (MOZ_UNLIKELY(!StartTracking(surface, aAutoLock))) {
+ discard.AppendElement(surface);
+ }
+ }
+
+ // Discard any that we failed to track.
+ for (auto iter = discard.begin(); iter != discard.end(); ++iter) {
+ Remove(*iter, /* aStopTracking */ false, aAutoLock);
+ }
+ }
+
+ void RemoveEntry(const ImageKey aImageKey, const SurfaceKey& aSurfaceKey,
+ const StaticMutexAutoLock& aAutoLock) {
+ RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
+ if (!cache) {
+ return; // No cached surfaces for this image.
+ }
+
+ RefPtr<CachedSurface> surface =
+ cache->Lookup(aSurfaceKey, /* aForAccess = */ false);
+ if (!surface) {
+ return; // Lookup in the per-image cache missed.
+ }
+
+ Remove(WrapNotNull(surface), /* aStopTracking */ true, aAutoLock);
+ }
+
+ class SurfaceTracker final
+ : public ExpirationTrackerImpl<CachedSurface, 2, StaticMutex,
+ StaticMutexAutoLock> {
+ public:
+ explicit SurfaceTracker(uint32_t aSurfaceCacheExpirationTimeMS)
+ : ExpirationTrackerImpl<CachedSurface, 2, StaticMutex,
+ StaticMutexAutoLock>(
+ aSurfaceCacheExpirationTimeMS, "SurfaceTracker") {}
+
+ protected:
+ void NotifyExpiredLocked(CachedSurface* aSurface,
+ const StaticMutexAutoLock& aAutoLock) override {
+ sInstance->Remove(WrapNotNull(aSurface), /* aStopTracking */ true,
+ aAutoLock);
+ }
+
+ void NotifyHandlerEndLocked(const StaticMutexAutoLock& aAutoLock) override {
+ sInstance->TakeDiscard(mDiscard, aAutoLock);
+ }
+
+ void NotifyHandlerEnd() override {
+ nsTArray<RefPtr<CachedSurface>> discard(std::move(mDiscard));
+ }
+
+ StaticMutex& GetMutex() override { return sInstanceMutex; }
+
+ nsTArray<RefPtr<CachedSurface>> mDiscard;
+ };
+
+ class MemoryPressureObserver final : public nsIObserver {
+ public:
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD Observe(nsISupports*, const char* aTopic,
+ const char16_t*) override {
+ nsTArray<RefPtr<CachedSurface>> discard;
+ {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (sInstance && strcmp(aTopic, "memory-pressure") == 0) {
+ sInstance->DiscardForMemoryPressure(lock);
+ sInstance->TakeDiscard(discard, lock);
+ }
+ }
+ return NS_OK;
+ }
+
+ private:
+ virtual ~MemoryPressureObserver() {}
+ };
+
+ nsTArray<CostEntry> mCosts;
+ nsRefPtrHashtable<nsPtrHashKey<Image>, ImageSurfaceCache> mImageCaches;
+ nsTArray<RefPtr<CachedSurface>> mCachedSurfacesDiscard;
+ SurfaceTracker mExpirationTracker;
+ RefPtr<MemoryPressureObserver> mMemoryPressureObserver;
+ nsTArray<RefPtr<image::Image>> mReleasingImagesOnMainThread;
+ const uint32_t mDiscardFactor;
+ const Cost mMaxCost;
+ Cost mAvailableCost;
+ Cost mLockedCost;
+ size_t mOverflowCount;
+ size_t mAlreadyPresentCount;
+ size_t mTableFailureCount;
+ size_t mTrackingFailureCount;
+};
+
+NS_IMPL_ISUPPORTS(SurfaceCacheImpl, nsIMemoryReporter)
+NS_IMPL_ISUPPORTS(SurfaceCacheImpl::MemoryPressureObserver, nsIObserver)
+
+///////////////////////////////////////////////////////////////////////////////
+// Public API
+///////////////////////////////////////////////////////////////////////////////
+
+/* static */
+void SurfaceCache::Initialize() {
+ // Initialize preferences.
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(!sInstance, "Shouldn't initialize more than once");
+
+ // See StaticPrefs for the default values of these preferences.
+
+ // Length of time before an unused surface is removed from the cache, in
+ // milliseconds.
+ uint32_t surfaceCacheExpirationTimeMS =
+ StaticPrefs::image_mem_surfacecache_min_expiration_ms_AtStartup();
+
+ // What fraction of the memory used by the surface cache we should discard
+ // when we get a memory pressure notification. This value is interpreted as
+ // 1/N, so 1 means to discard everything, 2 means to discard about half of the
+ // memory we're using, and so forth. We clamp it to avoid division by zero.
+ uint32_t surfaceCacheDiscardFactor =
+ max(StaticPrefs::image_mem_surfacecache_discard_factor_AtStartup(), 1u);
+
+ // Maximum size of the surface cache, in kilobytes.
+ uint64_t surfaceCacheMaxSizeKB =
+ StaticPrefs::image_mem_surfacecache_max_size_kb_AtStartup();
+
+ if (sizeof(uintptr_t) <= 4) {
+ // Limit surface cache to 1 GB if our address space is 32 bit.
+ surfaceCacheMaxSizeKB = 1024 * 1024;
+ }
+
+ // A knob determining the actual size of the surface cache. Currently the
+ // cache is (size of main memory) / (surface cache size factor) KB
+ // or (surface cache max size) KB, whichever is smaller. The formula
+ // may change in the future, though.
+ // For example, a value of 4 would yield a 256MB cache on a 1GB machine.
+ // The smallest machines we are likely to run this code on have 256MB
+ // of memory, which would yield a 64MB cache on this setting.
+ // We clamp this value to avoid division by zero.
+ uint32_t surfaceCacheSizeFactor =
+ max(StaticPrefs::image_mem_surfacecache_size_factor_AtStartup(), 1u);
+
+ // Compute the size of the surface cache.
+ uint64_t memorySize = PR_GetPhysicalMemorySize();
+ if (memorySize == 0) {
+#if !defined(__DragonFly__)
+ MOZ_ASSERT_UNREACHABLE("PR_GetPhysicalMemorySize not implemented here");
+#endif
+ memorySize = 256 * 1024 * 1024; // Fall back to 256MB.
+ }
+ uint64_t proposedSize = memorySize / surfaceCacheSizeFactor;
+ uint64_t surfaceCacheSizeBytes =
+ min(proposedSize, surfaceCacheMaxSizeKB * 1024);
+ uint32_t finalSurfaceCacheSizeBytes =
+ min(surfaceCacheSizeBytes, uint64_t(UINT32_MAX));
+
+ // Create the surface cache singleton with the requested settings. Note that
+ // the size is a limit that the cache may not grow beyond, but we do not
+ // actually allocate any storage for surfaces at this time.
+ sInstance = new SurfaceCacheImpl(surfaceCacheExpirationTimeMS,
+ surfaceCacheDiscardFactor,
+ finalSurfaceCacheSizeBytes);
+ sInstance->InitMemoryReporter();
+}
+
+/* static */
+void SurfaceCache::Shutdown() {
+ RefPtr<SurfaceCacheImpl> cache;
+ {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(sInstance, "No singleton - was Shutdown() called twice?");
+ cache = sInstance.forget();
+ }
+}
+
+/* static */
+LookupResult SurfaceCache::Lookup(const ImageKey aImageKey,
+ const SurfaceKey& aSurfaceKey,
+ bool aMarkUsed) {
+ nsTArray<RefPtr<CachedSurface>> discard;
+ LookupResult rv(MatchType::NOT_FOUND);
+
+ {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (!sInstance) {
+ return rv;
+ }
+
+ rv = sInstance->Lookup(aImageKey, aSurfaceKey, lock, aMarkUsed);
+ sInstance->TakeDiscard(discard, lock);
+ }
+
+ return rv;
+}
+
+/* static */
+LookupResult SurfaceCache::LookupBestMatch(const ImageKey aImageKey,
+ const SurfaceKey& aSurfaceKey,
+ bool aMarkUsed) {
+ nsTArray<RefPtr<CachedSurface>> discard;
+ LookupResult rv(MatchType::NOT_FOUND);
+
+ {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (!sInstance) {
+ return rv;
+ }
+
+ rv = sInstance->LookupBestMatch(aImageKey, aSurfaceKey, lock, aMarkUsed);
+ sInstance->TakeDiscard(discard, lock);
+ }
+
+ return rv;
+}
+
+/* static */
+InsertOutcome SurfaceCache::Insert(NotNull<ISurfaceProvider*> aProvider) {
+ nsTArray<RefPtr<CachedSurface>> discard;
+ InsertOutcome rv(InsertOutcome::FAILURE);
+
+ {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (!sInstance) {
+ return rv;
+ }
+
+ rv = sInstance->Insert(aProvider, /* aSetAvailable = */ false, lock);
+ sInstance->TakeDiscard(discard, lock);
+ }
+
+ return rv;
+}
+
+/* static */
+bool SurfaceCache::CanHold(const IntSize& aSize,
+ uint32_t aBytesPerPixel /* = 4 */) {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (!sInstance) {
+ return false;
+ }
+
+ Cost cost = ComputeCost(aSize, aBytesPerPixel);
+ return sInstance->CanHold(cost);
+}
+
+/* static */
+bool SurfaceCache::CanHold(size_t aSize) {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (!sInstance) {
+ return false;
+ }
+
+ return sInstance->CanHold(aSize);
+}
+
+/* static */
+void SurfaceCache::SurfaceAvailable(NotNull<ISurfaceProvider*> aProvider) {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (!sInstance) {
+ return;
+ }
+
+ sInstance->SurfaceAvailable(aProvider, lock);
+}
+
+/* static */
+void SurfaceCache::LockImage(const ImageKey aImageKey) {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (sInstance) {
+ return sInstance->LockImage(aImageKey);
+ }
+}
+
+/* static */
+void SurfaceCache::UnlockImage(const ImageKey aImageKey) {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (sInstance) {
+ return sInstance->UnlockImage(aImageKey, lock);
+ }
+}
+
+/* static */
+void SurfaceCache::UnlockEntries(const ImageKey aImageKey) {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (sInstance) {
+ return sInstance->UnlockEntries(aImageKey, lock);
+ }
+}
+
+/* static */
+void SurfaceCache::RemoveImage(const ImageKey aImageKey) {
+ RefPtr<ImageSurfaceCache> discard;
+ {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (sInstance) {
+ discard = sInstance->RemoveImage(aImageKey, lock);
+ }
+ }
+}
+
+/* static */
+void SurfaceCache::PruneImage(const ImageKey aImageKey) {
+ nsTArray<RefPtr<CachedSurface>> discard;
+ {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (sInstance) {
+ sInstance->PruneImage(aImageKey, lock);
+ sInstance->TakeDiscard(discard, lock);
+ }
+ }
+}
+
+/* static */
+bool SurfaceCache::InvalidateImage(const ImageKey aImageKey) {
+ nsTArray<RefPtr<CachedSurface>> discard;
+ bool rv = false;
+ {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (sInstance) {
+ rv = sInstance->InvalidateImage(aImageKey, lock);
+ sInstance->TakeDiscard(discard, lock);
+ }
+ }
+ return rv;
+}
+
+/* static */
+void SurfaceCache::DiscardAll() {
+ nsTArray<RefPtr<CachedSurface>> discard;
+ {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (sInstance) {
+ sInstance->DiscardAll(lock);
+ sInstance->TakeDiscard(discard, lock);
+ }
+ }
+}
+
+/* static */
+void SurfaceCache::ResetAnimation(const ImageKey aImageKey,
+ const SurfaceKey& aSurfaceKey) {
+ RefPtr<CachedSurface> surface;
+ nsTArray<RefPtr<CachedSurface>> discard;
+ {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (!sInstance) {
+ return;
+ }
+
+ surface =
+ sInstance->GetSurfaceForResetAnimation(aImageKey, aSurfaceKey, lock);
+ sInstance->TakeDiscard(discard, lock);
+ }
+
+ // Calling Reset will acquire the AnimationSurfaceProvider::mFramesMutex
+ // mutex. In other places we acquire the mFramesMutex then call into the
+ // surface cache (acquiring the surface cache mutex), so that determines a
+ // lock order which we must obey by calling Reset after releasing the surface
+ // cache mutex.
+ if (surface) {
+ DrawableSurface drawableSurface =
+ surface->GetDrawableSurfaceEvenIfPlaceholder();
+ if (drawableSurface) {
+ MOZ_ASSERT(surface->GetSurfaceKey() == aSurfaceKey,
+ "ResetAnimation() not returning an exact match?");
+
+ drawableSurface.Reset();
+ }
+ }
+}
+
+/* static */
+void SurfaceCache::CollectSizeOfSurfaces(
+ const ImageKey aImageKey, nsTArray<SurfaceMemoryCounter>& aCounters,
+ MallocSizeOf aMallocSizeOf) {
+ nsTArray<RefPtr<CachedSurface>> discard;
+ {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (!sInstance) {
+ return;
+ }
+
+ sInstance->CollectSizeOfSurfaces(aImageKey, aCounters, aMallocSizeOf, lock);
+ sInstance->TakeDiscard(discard, lock);
+ }
+}
+
+/* static */
+size_t SurfaceCache::MaximumCapacity() {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (!sInstance) {
+ return 0;
+ }
+
+ return sInstance->MaximumCapacity();
+}
+
+/* static */
+bool SurfaceCache::IsLegalSize(const IntSize& aSize) {
+ // reject over-wide or over-tall images
+ const int32_t k64KLimit = 0x0000FFFF;
+ if (MOZ_UNLIKELY(aSize.width > k64KLimit || aSize.height > k64KLimit)) {
+ NS_WARNING("image too big");
+ return false;
+ }
+
+ // protect against invalid sizes
+ if (MOZ_UNLIKELY(aSize.height <= 0 || aSize.width <= 0)) {
+ return false;
+ }
+
+ // check to make sure we don't overflow a 32-bit
+ CheckedInt32 requiredBytes =
+ CheckedInt32(aSize.width) * CheckedInt32(aSize.height) * 4;
+ if (MOZ_UNLIKELY(!requiredBytes.isValid())) {
+ NS_WARNING("width or height too large");
+ return false;
+ }
+ return true;
+}
+
+IntSize SurfaceCache::ClampVectorSize(const IntSize& aSize) {
+ // If we exceed the maximum, we need to scale the size downwards to fit.
+ // It shouldn't get here if it is significantly larger because
+ // VectorImage::UseSurfaceCacheForSize should prevent us from requesting
+ // a rasterized version of a surface greater than 4x the maximum.
+ int32_t maxSizeKB =
+ StaticPrefs::image_cache_max_rasterized_svg_threshold_kb();
+ if (maxSizeKB <= 0) {
+ return aSize;
+ }
+
+ int64_t proposedKB = int64_t(aSize.width) * aSize.height / 256;
+ if (maxSizeKB >= proposedKB) {
+ return aSize;
+ }
+
+ double scale = sqrt(double(maxSizeKB) / proposedKB);
+ return IntSize(int32_t(scale * aSize.width), int32_t(scale * aSize.height));
+}
+
+IntSize SurfaceCache::ClampSize(ImageKey aImageKey, const IntSize& aSize) {
+ if (aImageKey->GetType() != imgIContainer::TYPE_VECTOR) {
+ return aSize;
+ }
+
+ return ClampVectorSize(aSize);
+}
+
+/* static */
+void SurfaceCache::ReleaseImageOnMainThread(
+ already_AddRefed<image::Image> aImage, bool aAlwaysProxy) {
+ if (NS_IsMainThread() && !aAlwaysProxy) {
+ RefPtr<image::Image> image = std::move(aImage);
+ return;
+ }
+
+ // Don't try to dispatch the release after shutdown, we'll just leak the
+ // runnable.
+ if (AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownFinal)) {
+ return;
+ }
+
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (sInstance) {
+ sInstance->ReleaseImageOnMainThread(std::move(aImage), lock);
+ } else {
+ NS_ReleaseOnMainThread("SurfaceCache::ReleaseImageOnMainThread",
+ std::move(aImage), /* aAlwaysProxy */ true);
+ }
+}
+
+/* static */
+void SurfaceCache::ClearReleasingImages() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsTArray<RefPtr<image::Image>> images;
+ {
+ StaticMutexAutoLock lock(sInstanceMutex);
+ if (sInstance) {
+ sInstance->TakeReleasingImages(images, lock);
+ }
+ }
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/SurfaceCache.h b/image/SurfaceCache.h
new file mode 100644
index 0000000000..864a6ffbc4
--- /dev/null
+++ b/image/SurfaceCache.h
@@ -0,0 +1,509 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * SurfaceCache is a service for caching temporary surfaces and decoded image
+ * data in imagelib.
+ */
+
+#ifndef mozilla_image_SurfaceCache_h
+#define mozilla_image_SurfaceCache_h
+
+#include "mozilla/HashFunctions.h" // for HashGeneric and AddToHash
+#include "mozilla/Maybe.h" // for Maybe
+#include "mozilla/MemoryReporting.h" // for MallocSizeOf
+#include "mozilla/NotNull.h"
+#include "mozilla/SVGImageContext.h" // for SVGImageContext
+#include "mozilla/gfx/2D.h" // for SourceSurface
+#include "mozilla/gfx/Point.h" // for mozilla::gfx::IntSize
+#include "gfx2DGlue.h"
+#include "gfxPoint.h" // for gfxSize
+#include "nsCOMPtr.h" // for already_AddRefed
+#include "ImageRegion.h"
+#include "PlaybackType.h"
+#include "SurfaceFlags.h"
+
+namespace mozilla {
+namespace image {
+
+class ImageResource;
+class ISurfaceProvider;
+class LookupResult;
+class SurfaceCacheImpl;
+struct SurfaceMemoryCounter;
+
+/*
+ * ImageKey contains the information we need to look up all SurfaceCache entries
+ * for a particular image.
+ */
+using ImageKey = ImageResource*;
+
+/*
+ * SurfaceKey contains the information we need to look up a specific
+ * SurfaceCache entry. Together with an ImageKey, this uniquely identifies the
+ * surface.
+ *
+ * Callers should construct a SurfaceKey using the appropriate helper function
+ * for their image type - either RasterSurfaceKey or VectorSurfaceKey.
+ */
+class SurfaceKey {
+ typedef gfx::IntSize IntSize;
+
+ public:
+ bool operator==(const SurfaceKey& aOther) const {
+ return aOther.mSize == mSize && aOther.mRegion == mRegion &&
+ aOther.mSVGContext == mSVGContext && aOther.mPlayback == mPlayback &&
+ aOther.mFlags == mFlags;
+ }
+
+ PLDHashNumber Hash() const {
+ PLDHashNumber hash = HashGeneric(mSize.width, mSize.height);
+ hash = AddToHash(hash, mRegion.map(HashIIR).valueOr(0));
+ hash = AddToHash(hash, HashSIC(mSVGContext));
+ hash = AddToHash(hash, uint8_t(mPlayback), uint32_t(mFlags));
+ return hash;
+ }
+
+ SurfaceKey CloneWithSize(const IntSize& aSize) const {
+ return SurfaceKey(aSize, mRegion, mSVGContext, mPlayback, mFlags);
+ }
+
+ const IntSize& Size() const { return mSize; }
+ const Maybe<ImageIntRegion>& Region() const { return mRegion; }
+ const SVGImageContext& SVGContext() const { return mSVGContext; }
+ PlaybackType Playback() const { return mPlayback; }
+ SurfaceFlags Flags() const { return mFlags; }
+
+ private:
+ SurfaceKey(const IntSize& aSize, const Maybe<ImageIntRegion>& aRegion,
+ const SVGImageContext& aSVGContext, PlaybackType aPlayback,
+ SurfaceFlags aFlags)
+ : mSize(aSize),
+ mRegion(aRegion),
+ mSVGContext(aSVGContext),
+ mPlayback(aPlayback),
+ mFlags(aFlags) {}
+
+ static PLDHashNumber HashIIR(const ImageIntRegion& aIIR) {
+ return aIIR.Hash();
+ }
+
+ static PLDHashNumber HashSIC(const SVGImageContext& aSIC) {
+ return aSIC.Hash();
+ }
+
+ friend SurfaceKey RasterSurfaceKey(const IntSize&, SurfaceFlags,
+ PlaybackType);
+ friend SurfaceKey VectorSurfaceKey(const IntSize&, const SVGImageContext&);
+ friend SurfaceKey VectorSurfaceKey(const IntSize&,
+ const Maybe<ImageIntRegion>&,
+ const SVGImageContext&, SurfaceFlags,
+ PlaybackType);
+
+ IntSize mSize;
+ Maybe<ImageIntRegion> mRegion;
+ SVGImageContext mSVGContext;
+ PlaybackType mPlayback;
+ SurfaceFlags mFlags;
+};
+
+inline SurfaceKey RasterSurfaceKey(const gfx::IntSize& aSize,
+ SurfaceFlags aFlags,
+ PlaybackType aPlayback) {
+ return SurfaceKey(aSize, Nothing(), SVGImageContext(), aPlayback, aFlags);
+}
+
+inline SurfaceKey VectorSurfaceKey(const gfx::IntSize& aSize,
+ const Maybe<ImageIntRegion>& aRegion,
+ const SVGImageContext& aSVGContext,
+ SurfaceFlags aFlags,
+ PlaybackType aPlayback) {
+ return SurfaceKey(aSize, aRegion, aSVGContext, aPlayback, aFlags);
+}
+
+inline SurfaceKey VectorSurfaceKey(const gfx::IntSize& aSize,
+ const SVGImageContext& aSVGContext) {
+ // We don't care about aFlags for VectorImage because none of the flags we
+ // have right now influence VectorImage's rendering. If we add a new flag that
+ // *does* affect how a VectorImage renders, we'll have to change this.
+ // Similarly, we don't accept a PlaybackType parameter because we don't
+ // currently cache frames of animated SVG images.
+ return SurfaceKey(aSize, Nothing(), aSVGContext, PlaybackType::eStatic,
+ DefaultSurfaceFlags());
+}
+
+/**
+ * AvailabilityState is used to track whether an ISurfaceProvider has a surface
+ * available or is just a placeholder.
+ *
+ * To ensure that availability changes are atomic (and especially that internal
+ * SurfaceCache code doesn't have to deal with asynchronous availability
+ * changes), an ISurfaceProvider which starts as a placeholder can only reveal
+ * the fact that it now has a surface available via a call to
+ * SurfaceCache::SurfaceAvailable().
+ *
+ * It also tracks whether or not there are "explicit" users of this surface
+ * which will not accept substitutes. This is used by SurfaceCache when pruning
+ * unnecessary surfaces from the cache.
+ */
+class AvailabilityState {
+ public:
+ static AvailabilityState StartAvailable() { return AvailabilityState(true); }
+ static AvailabilityState StartAsPlaceholder() {
+ return AvailabilityState(false);
+ }
+
+ bool IsAvailable() const { return mIsAvailable; }
+ bool IsPlaceholder() const { return !mIsAvailable; }
+ bool CannotSubstitute() const { return mCannotSubstitute; }
+
+ void SetCannotSubstitute() { mCannotSubstitute = true; }
+
+ private:
+ friend class SurfaceCacheImpl;
+
+ explicit AvailabilityState(bool aIsAvailable)
+ : mIsAvailable(aIsAvailable), mCannotSubstitute(false) {}
+
+ void SetAvailable() { mIsAvailable = true; }
+
+ bool mIsAvailable : 1;
+ bool mCannotSubstitute : 1;
+};
+
+enum class InsertOutcome : uint8_t {
+ SUCCESS, // Success (but see Insert documentation).
+ FAILURE, // Couldn't insert (e.g., for capacity reasons).
+ FAILURE_ALREADY_PRESENT // A surface with the same key is already present.
+};
+
+/**
+ * SurfaceCache is an ImageLib-global service that allows caching of decoded
+ * image surfaces, temporary surfaces (e.g. for caching rotated or clipped
+ * versions of images), or dynamically generated surfaces (e.g. for animations).
+ * SurfaceCache entries normally expire from the cache automatically if they go
+ * too long without being accessed.
+ *
+ * Because SurfaceCache must support both normal surfaces and dynamically
+ * generated surfaces, it does not actually hold surfaces directly. Instead, it
+ * holds ISurfaceProvider objects which can provide access to a surface when
+ * requested; SurfaceCache doesn't care about the details of how this is
+ * accomplished.
+ *
+ * Sometime it's useful to temporarily prevent entries from expiring from the
+ * cache. This is most often because losing the data could harm the user
+ * experience (for example, we often don't want to allow surfaces that are
+ * currently visible to expire) or because it's not possible to rematerialize
+ * the surface. SurfaceCache supports this through the use of image locking; see
+ * the comments for Insert() and LockImage() for more details.
+ *
+ * Any image which stores surfaces in the SurfaceCache *must* ensure that it
+ * calls RemoveImage() before it is destroyed. See the comments for
+ * RemoveImage() for more details.
+ */
+struct SurfaceCache {
+ typedef gfx::IntSize IntSize;
+
+ /**
+ * Initialize static data. Called during imagelib module initialization.
+ */
+ static void Initialize();
+
+ /**
+ * Release static data. Called during imagelib module shutdown.
+ */
+ static void Shutdown();
+
+ /**
+ * Looks up the requested cache entry and returns a drawable reference to its
+ * associated surface.
+ *
+ * If the image associated with the cache entry is locked, then the entry will
+ * be locked before it is returned.
+ *
+ * If a matching ISurfaceProvider was found in the cache, but SurfaceCache
+ * couldn't obtain a surface from it (e.g. because it had stored its surface
+ * in a volatile buffer which was discarded by the OS) then it is
+ * automatically removed from the cache and an empty LookupResult is returned.
+ * Note that this will never happen to ISurfaceProviders associated with a
+ * locked image; SurfaceCache tells such ISurfaceProviders to keep a strong
+ * references to their data internally.
+ *
+ * @param aImageKey Key data identifying which image the cache entry
+ * belongs to.
+ * @param aSurfaceKey Key data which uniquely identifies the requested
+ * cache entry.
+ * @return a LookupResult which will contain a DrawableSurface
+ * if the cache entry was found.
+ */
+ static LookupResult Lookup(const ImageKey aImageKey,
+ const SurfaceKey& aSurfaceKey, bool aMarkUsed);
+
+ /**
+ * Looks up the best matching cache entry and returns a drawable reference to
+ * its associated surface.
+ *
+ * The result may vary from the requested cache entry only in terms of size.
+ *
+ * @param aImageKey Key data identifying which image the cache entry
+ * belongs to.
+ * @param aSurfaceKey Key data which uniquely identifies the requested
+ * cache entry.
+ * @return a LookupResult which will contain a DrawableSurface
+ * if a cache entry similar to the one the caller
+ * requested could be found. Callers can use
+ * LookupResult::IsExactMatch() to check whether the
+ * returned surface exactly matches @aSurfaceKey.
+ */
+ static LookupResult LookupBestMatch(const ImageKey aImageKey,
+ const SurfaceKey& aSurfaceKey,
+ bool aMarkUsed);
+
+ /**
+ * Insert an ISurfaceProvider into the cache. If an entry with the same
+ * ImageKey and SurfaceKey is already in the cache, Insert returns
+ * FAILURE_ALREADY_PRESENT. If a matching placeholder is already present, it
+ * is replaced.
+ *
+ * Cache entries will never expire as long as they remain locked, but if they
+ * become unlocked, they can expire either because the SurfaceCache runs out
+ * of capacity or because they've gone too long without being used. When it
+ * is first inserted, a cache entry is locked if its associated image is
+ * locked. When that image is later unlocked, the cache entry becomes
+ * unlocked too. To become locked again at that point, two things must happen:
+ * the image must become locked again (via LockImage()), and the cache entry
+ * must be touched again (via one of the Lookup() functions).
+ *
+ * All of this means that a very particular procedure has to be followed for
+ * cache entries which cannot be rematerialized. First, they must be inserted
+ * *after* the image is locked with LockImage(); if you use the other order,
+ * the cache entry might expire before LockImage() gets called or before the
+ * entry is touched again by Lookup(). Second, the image they are associated
+ * with must never be unlocked.
+ *
+ * If a cache entry cannot be rematerialized, it may be important to know
+ * whether it was inserted into the cache successfully. Insert() returns
+ * FAILURE if it failed to insert the cache entry, which could happen because
+ * of capacity reasons, or because it was already freed by the OS. If the
+ * cache entry isn't associated with a locked image, checking for SUCCESS or
+ * FAILURE is useless: the entry might expire immediately after being
+ * inserted, even though Insert() returned SUCCESS. Thus, many callers do not
+ * need to check the result of Insert() at all.
+ *
+ * @param aProvider The new cache entry to insert into the cache.
+ * @return SUCCESS if the cache entry was inserted successfully. (But see
+ * above for more information about when you should check this.)
+ * FAILURE if the cache entry could not be inserted, e.g. for capacity
+ * reasons. (But see above for more information about when you
+ * should check this.)
+ * FAILURE_ALREADY_PRESENT if an entry with the same ImageKey and
+ * SurfaceKey already exists in the cache.
+ */
+ static InsertOutcome Insert(NotNull<ISurfaceProvider*> aProvider);
+
+ /**
+ * Mark the cache entry @aProvider as having an available surface. This turns
+ * a placeholder cache entry into a normal cache entry. The cache entry
+ * becomes locked if the associated image is locked; otherwise, it starts in
+ * the unlocked state.
+ *
+ * If the cache entry containing @aProvider has already been evicted from the
+ * surface cache, this function has no effect.
+ *
+ * It's illegal to call this function if @aProvider is not a placeholder; by
+ * definition, non-placeholder ISurfaceProviders should have a surface
+ * available already.
+ *
+ * @param aProvider The cache entry that now has a surface available.
+ */
+ static void SurfaceAvailable(NotNull<ISurfaceProvider*> aProvider);
+
+ /**
+ * Checks if a surface of a given size could possibly be stored in the cache.
+ * If CanHold() returns false, Insert() will always fail to insert the
+ * surface, but the inverse is not true: Insert() may take more information
+ * into account than just image size when deciding whether to cache the
+ * surface, so Insert() may still fail even if CanHold() returns true.
+ *
+ * Use CanHold() to avoid the need to create a temporary surface when we know
+ * for sure the cache can't hold it.
+ *
+ * @param aSize The dimensions of a surface in pixels.
+ * @param aBytesPerPixel How many bytes each pixel of the surface requires.
+ * Defaults to 4, which is appropriate for RGBA or RGBX
+ * images.
+ *
+ * @return false if the surface cache can't hold a surface of that size.
+ */
+ static bool CanHold(const IntSize& aSize, uint32_t aBytesPerPixel = 4);
+ static bool CanHold(size_t aSize);
+
+ /**
+ * Locks an image. Any of the image's cache entries which are either inserted
+ * or accessed while the image is locked will not expire.
+ *
+ * Locking an image does not automatically lock that image's existing cache
+ * entries. A call to LockImage() guarantees that entries which are inserted
+ * afterward will not expire before the next call to UnlockImage() or
+ * UnlockSurfaces() for that image. Cache entries that are accessed via
+ * Lookup() or LookupBestMatch() after a LockImage() call will also not expire
+ * until the next UnlockImage() or UnlockSurfaces() call for that image. Any
+ * other cache entries owned by the image may expire at any time.
+ *
+ * All of an image's cache entries are removed by RemoveImage(), whether the
+ * image is locked or not.
+ *
+ * It's safe to call LockImage() on an image that's already locked; this has
+ * no effect.
+ *
+ * You must always unlock any image you lock. You may do this explicitly by
+ * calling UnlockImage(), or implicitly by calling RemoveImage(). Since you're
+ * required to call RemoveImage() when you destroy an image, this doesn't
+ * impose any additional requirements, but it's preferable to call
+ * UnlockImage() earlier if it's possible.
+ *
+ * @param aImageKey The image to lock.
+ */
+ static void LockImage(const ImageKey aImageKey);
+
+ /**
+ * Unlocks an image, allowing any of its cache entries to expire at any time.
+ *
+ * It's OK to call UnlockImage() on an image that's already unlocked; this has
+ * no effect.
+ *
+ * @param aImageKey The image to unlock.
+ */
+ static void UnlockImage(const ImageKey aImageKey);
+
+ /**
+ * Unlocks the existing cache entries of an image, allowing them to expire at
+ * any time.
+ *
+ * This does not unlock the image itself, so accessing the cache entries via
+ * Lookup() or LookupBestMatch() will lock them again, and prevent them from
+ * expiring.
+ *
+ * This is intended to be used in situations where it's no longer clear that
+ * all of the cache entries owned by an image are needed. Calling
+ * UnlockSurfaces() and then taking some action that will cause Lookup() to
+ * touch any cache entries that are still useful will permit the remaining
+ * entries to expire from the cache.
+ *
+ * If the image is unlocked, this has no effect.
+ *
+ * @param aImageKey The image which should have its existing cache entries
+ * unlocked.
+ */
+ static void UnlockEntries(const ImageKey aImageKey);
+
+ /**
+ * Removes all cache entries (including placeholders) associated with the
+ * given image from the cache. If the image is locked, it is automatically
+ * unlocked.
+ *
+ * This MUST be called, at a minimum, when an Image which could be storing
+ * entries in the surface cache is destroyed. If another image were allocated
+ * at the same address it could result in subtle, difficult-to-reproduce bugs.
+ *
+ * @param aImageKey The image which should be removed from the cache.
+ */
+ static void RemoveImage(const ImageKey aImageKey);
+
+ /**
+ * Attempts to remove cache entries (including placeholders) associated with
+ * the given image from the cache, assuming there is an equivalent entry that
+ * it is able substitute that entry with. Note that this only applies if the
+ * image is in factor of 2 mode. If it is not, this operation does nothing.
+ *
+ * @param aImageKey The image whose cache which should be pruned.
+ */
+ static void PruneImage(const ImageKey aImageKey);
+
+ /**
+ * Removes all rasterized cache entries (including placeholders) associated
+ * with the given image from the cache. Any blob recordings are marked as
+ * dirty and must be regenerated.
+ *
+ * @param aImageKey The image whose cache which should be regenerated.
+ *
+ * @returns true if any recordings were invalidated, else false.
+ */
+ static bool InvalidateImage(const ImageKey aImageKey);
+
+ /**
+ * Evicts all evictable entries from the cache.
+ *
+ * All entries are evictable except for entries associated with locked images.
+ * Non-evictable entries can only be removed by RemoveImage().
+ */
+ static void DiscardAll();
+
+ /**
+ * Calls Reset on the ISurfaceProvider (which is currently only implemented
+ * for AnimationSurfaceProvider). This is needed because we need to call Reset
+ * on AnimationSurfaceProvider while they are in placeholder status and there
+ * is no way to access a surface cache entry from outside of the surface cache
+ * when it's in placeholder status.
+ */
+ static void ResetAnimation(const ImageKey aImageKey,
+ const SurfaceKey& aSurfaceKey);
+
+ /**
+ * Collects an accounting of the surfaces contained in the SurfaceCache for
+ * the given image, along with their size and various other metadata.
+ *
+ * This is intended for use with memory reporting.
+ *
+ * @param aImageKey The image to report memory usage for.
+ * @param aCounters An array into which the report for each surface will
+ * be written.
+ * @param aMallocSizeOf A fallback malloc memory reporting function.
+ */
+ static void CollectSizeOfSurfaces(const ImageKey aImageKey,
+ nsTArray<SurfaceMemoryCounter>& aCounters,
+ MallocSizeOf aMallocSizeOf);
+
+ /**
+ * @return maximum capacity of the SurfaceCache in bytes. This is only exposed
+ * for use by tests; normal code should use CanHold() instead.
+ */
+ static size_t MaximumCapacity();
+
+ /**
+ * @return true if the given size is valid.
+ */
+ static bool IsLegalSize(const IntSize& aSize);
+
+ /**
+ * @return clamped size for the given vector image size to rasterize at.
+ */
+ static IntSize ClampVectorSize(const IntSize& aSize);
+
+ /**
+ * @return clamped size for the given image and size to rasterize at.
+ */
+ static IntSize ClampSize(const ImageKey aImageKey, const IntSize& aSize);
+
+ /**
+ * Release image on main thread.
+ * The function uses SurfaceCache to release pending releasing images quickly.
+ */
+ static void ReleaseImageOnMainThread(already_AddRefed<image::Image> aImage,
+ bool aAlwaysProxy = false);
+
+ /**
+ * Clear all pending releasing images.
+ */
+ static void ClearReleasingImages();
+
+ private:
+ virtual ~SurfaceCache() = 0; // Forbid instantiation.
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_SurfaceCache_h
diff --git a/image/SurfaceCacheUtils.cpp b/image/SurfaceCacheUtils.cpp
new file mode 100644
index 0000000000..e92197ca7c
--- /dev/null
+++ b/image/SurfaceCacheUtils.cpp
@@ -0,0 +1,17 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SurfaceCacheUtils.h"
+
+#include "SurfaceCache.h"
+
+namespace mozilla {
+namespace image {
+
+/* static */
+void SurfaceCacheUtils::DiscardAll() { SurfaceCache::DiscardAll(); }
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/SurfaceCacheUtils.h b/image/SurfaceCacheUtils.h
new file mode 100644
index 0000000000..0e1e2431f9
--- /dev/null
+++ b/image/SurfaceCacheUtils.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_SurfaceCacheUtils_h
+#define mozilla_image_SurfaceCacheUtils_h
+
+/**
+ * SurfaceCacheUtils provides an ImageLib-external API to interact with
+ * ImageLib's SurfaceCache.
+ */
+
+namespace mozilla {
+namespace image {
+
+class SurfaceCacheUtils {
+ public:
+ /**
+ * Evicts all evictable entries from the surface cache.
+ *
+ * See the documentation for SurfaceCache::DiscardAll() for the details.
+ */
+ static void DiscardAll();
+
+ private:
+ virtual ~SurfaceCacheUtils() = 0; // Forbid instantiation.
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_SurfaceCacheUtils_h
diff --git a/image/SurfaceFilters.h b/image/SurfaceFilters.h
new file mode 100644
index 0000000000..92c406386a
--- /dev/null
+++ b/image/SurfaceFilters.h
@@ -0,0 +1,1454 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * This header contains various SurfaceFilter implementations that apply
+ * transformations to image data, for usage with SurfacePipe.
+ */
+
+#ifndef mozilla_image_SurfaceFilters_h
+#define mozilla_image_SurfaceFilters_h
+
+#include <algorithm>
+#include <stdint.h>
+#include <string.h>
+
+#include "mozilla/Likely.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Swizzle.h"
+#include "skia/src/core/SkBlitRow.h"
+
+#include "DownscalingFilter.h"
+#include "SurfaceCache.h"
+#include "SurfacePipe.h"
+
+namespace mozilla {
+namespace image {
+
+//////////////////////////////////////////////////////////////////////////////
+// SwizzleFilter
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename Next>
+class SwizzleFilter;
+
+/**
+ * A configuration struct for SwizzleFilter.
+ */
+struct SwizzleConfig {
+ template <typename Next>
+ using Filter = SwizzleFilter<Next>;
+ gfx::SurfaceFormat mInFormat;
+ gfx::SurfaceFormat mOutFormat;
+ bool mPremultiplyAlpha;
+};
+
+/**
+ * SwizzleFilter performs premultiplication, swizzling and unpacking on
+ * rows written to it. It can use accelerated methods to perform these
+ * operations if supported on the platform.
+ *
+ * The 'Next' template parameter specifies the next filter in the chain.
+ */
+template <typename Next>
+class SwizzleFilter final : public SurfaceFilter {
+ public:
+ SwizzleFilter() : mSwizzleFn(nullptr) {}
+
+ template <typename... Rest>
+ nsresult Configure(const SwizzleConfig& aConfig, const Rest&... aRest) {
+ nsresult rv = mNext.Configure(aRest...);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ if (aConfig.mPremultiplyAlpha) {
+ mSwizzleFn = gfx::PremultiplyRow(aConfig.mInFormat, aConfig.mOutFormat);
+ } else {
+ mSwizzleFn = gfx::SwizzleRow(aConfig.mInFormat, aConfig.mOutFormat);
+ }
+
+ if (!mSwizzleFn) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ ConfigureFilter(mNext.InputSize(), sizeof(uint32_t));
+ return NS_OK;
+ }
+
+ Maybe<SurfaceInvalidRect> TakeInvalidRect() override {
+ return mNext.TakeInvalidRect();
+ }
+
+ protected:
+ uint8_t* DoResetToFirstRow() override { return mNext.ResetToFirstRow(); }
+
+ uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
+ uint8_t* rowPtr = mNext.CurrentRowPointer();
+ if (!rowPtr) {
+ return nullptr; // We already got all the input rows we expect.
+ }
+
+ mSwizzleFn(aInputRow, rowPtr, mNext.InputSize().width);
+ return mNext.AdvanceRow();
+ }
+
+ uint8_t* DoAdvanceRow() override {
+ return DoAdvanceRowFromBuffer(mNext.CurrentRowPointer());
+ }
+
+ Next mNext; /// The next SurfaceFilter in the chain.
+
+ gfx::SwizzleRowFn mSwizzleFn;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// ColorManagementFilter
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename Next>
+class ColorManagementFilter;
+
+/**
+ * A configuration struct for ColorManagementFilter.
+ */
+struct ColorManagementConfig {
+ template <typename Next>
+ using Filter = ColorManagementFilter<Next>;
+ qcms_transform* mTransform;
+};
+
+/**
+ * ColorManagementFilter performs color transforms with qcms on rows written
+ * to it.
+ *
+ * The 'Next' template parameter specifies the next filter in the chain.
+ */
+template <typename Next>
+class ColorManagementFilter final : public SurfaceFilter {
+ public:
+ ColorManagementFilter() : mTransform(nullptr) {}
+
+ template <typename... Rest>
+ nsresult Configure(const ColorManagementConfig& aConfig,
+ const Rest&... aRest) {
+ nsresult rv = mNext.Configure(aRest...);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ if (!aConfig.mTransform) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ mTransform = aConfig.mTransform;
+ ConfigureFilter(mNext.InputSize(), sizeof(uint32_t));
+ return NS_OK;
+ }
+
+ Maybe<SurfaceInvalidRect> TakeInvalidRect() override {
+ return mNext.TakeInvalidRect();
+ }
+
+ protected:
+ uint8_t* DoResetToFirstRow() override { return mNext.ResetToFirstRow(); }
+
+ uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
+ qcms_transform_data(mTransform, aInputRow, mNext.CurrentRowPointer(),
+ mNext.InputSize().width);
+ return mNext.AdvanceRow();
+ }
+
+ uint8_t* DoAdvanceRow() override {
+ return DoAdvanceRowFromBuffer(mNext.CurrentRowPointer());
+ }
+
+ Next mNext; /// The next SurfaceFilter in the chain.
+
+ qcms_transform* mTransform;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// DeinterlacingFilter
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename PixelType, typename Next>
+class DeinterlacingFilter;
+
+/**
+ * A configuration struct for DeinterlacingFilter.
+ *
+ * The 'PixelType' template parameter should be either uint32_t (for output to a
+ * SurfaceSink) or uint8_t (for output to a PalettedSurfaceSink).
+ */
+template <typename PixelType>
+struct DeinterlacingConfig {
+ template <typename Next>
+ using Filter = DeinterlacingFilter<PixelType, Next>;
+ bool mProgressiveDisplay; /// If true, duplicate rows during deinterlacing
+ /// to make progressive display look better, at
+ /// the cost of some performance.
+};
+
+/**
+ * DeinterlacingFilter performs deinterlacing by reordering the rows that are
+ * written to it.
+ *
+ * The 'PixelType' template parameter should be either uint32_t (for output to a
+ * SurfaceSink) or uint8_t (for output to a PalettedSurfaceSink).
+ *
+ * The 'Next' template parameter specifies the next filter in the chain.
+ */
+template <typename PixelType, typename Next>
+class DeinterlacingFilter final : public SurfaceFilter {
+ public:
+ DeinterlacingFilter()
+ : mInputRow(0), mOutputRow(0), mPass(0), mProgressiveDisplay(true) {}
+
+ template <typename... Rest>
+ nsresult Configure(const DeinterlacingConfig<PixelType>& aConfig,
+ const Rest&... aRest) {
+ nsresult rv = mNext.Configure(aRest...);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ gfx::IntSize outputSize = mNext.InputSize();
+ mProgressiveDisplay = aConfig.mProgressiveDisplay;
+
+ const CheckedUint32 bufferSize = CheckedUint32(outputSize.width) *
+ CheckedUint32(outputSize.height) *
+ CheckedUint32(sizeof(PixelType));
+
+ // Use the size of the SurfaceCache as a heuristic to avoid gigantic
+ // allocations. Even if DownscalingFilter allowed us to allocate space for
+ // the output image, the deinterlacing buffer may still be too big, and
+ // fallible allocation won't always save us in the presence of overcommit.
+ if (!bufferSize.isValid() || !SurfaceCache::CanHold(bufferSize.value())) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ // Allocate the buffer, which contains deinterlaced scanlines of the image.
+ // The buffer is necessary so that we can output rows which have already
+ // been deinterlaced again on subsequent passes. Since a later stage in the
+ // pipeline may be transforming the rows it receives (for example, by
+ // downscaling them), the rows may no longer exist in their original form on
+ // the surface itself.
+ mBuffer.reset(new (fallible) uint8_t[bufferSize.value()]);
+ if (MOZ_UNLIKELY(!mBuffer)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ // Clear the buffer to avoid writing uninitialized memory to the output.
+ memset(mBuffer.get(), 0, bufferSize.value());
+
+ ConfigureFilter(outputSize, sizeof(PixelType));
+ return NS_OK;
+ }
+
+ Maybe<SurfaceInvalidRect> TakeInvalidRect() override {
+ return mNext.TakeInvalidRect();
+ }
+
+ protected:
+ uint8_t* DoResetToFirstRow() override {
+ mNext.ResetToFirstRow();
+ mPass = 0;
+ mInputRow = 0;
+ mOutputRow = InterlaceOffset(mPass);
+ return GetRowPointer(mOutputRow);
+ }
+
+ uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
+ CopyInputRow(aInputRow);
+ return DoAdvanceRow();
+ }
+
+ uint8_t* DoAdvanceRow() override {
+ if (mPass >= 4) {
+ return nullptr; // We already finished all passes.
+ }
+ if (mInputRow >= InputSize().height) {
+ return nullptr; // We already got all the input rows we expect.
+ }
+
+ // Duplicate from the first Haeberli row to the remaining Haeberli rows
+ // within the buffer.
+ DuplicateRows(
+ HaeberliOutputStartRow(mPass, mProgressiveDisplay, mOutputRow),
+ HaeberliOutputUntilRow(mPass, mProgressiveDisplay, InputSize(),
+ mOutputRow));
+
+ // Write the current set of Haeberli rows (which contains the current row)
+ // to the next stage in the pipeline.
+ OutputRows(HaeberliOutputStartRow(mPass, mProgressiveDisplay, mOutputRow),
+ HaeberliOutputUntilRow(mPass, mProgressiveDisplay, InputSize(),
+ mOutputRow));
+
+ // Determine which output row the next input row corresponds to.
+ bool advancedPass = false;
+ uint32_t stride = InterlaceStride(mPass);
+ int32_t nextOutputRow = mOutputRow + stride;
+ while (nextOutputRow >= InputSize().height) {
+ // Copy any remaining rows from the buffer.
+ if (!advancedPass) {
+ OutputRows(HaeberliOutputUntilRow(mPass, mProgressiveDisplay,
+ InputSize(), mOutputRow),
+ InputSize().height);
+ }
+
+ // We finished the current pass; advance to the next one.
+ mPass++;
+ if (mPass >= 4) {
+ return nullptr; // Finished all passes.
+ }
+
+ // Tell the next pipeline stage that we're starting the next pass.
+ mNext.ResetToFirstRow();
+
+ // Update our state to reflect the pass change.
+ advancedPass = true;
+ stride = InterlaceStride(mPass);
+ nextOutputRow = InterlaceOffset(mPass);
+ }
+
+ MOZ_ASSERT(nextOutputRow >= 0);
+ MOZ_ASSERT(nextOutputRow < InputSize().height);
+
+ MOZ_ASSERT(
+ HaeberliOutputStartRow(mPass, mProgressiveDisplay, nextOutputRow) >= 0);
+ MOZ_ASSERT(HaeberliOutputStartRow(mPass, mProgressiveDisplay,
+ nextOutputRow) < InputSize().height);
+ MOZ_ASSERT(HaeberliOutputStartRow(mPass, mProgressiveDisplay,
+ nextOutputRow) <= nextOutputRow);
+
+ MOZ_ASSERT(HaeberliOutputUntilRow(mPass, mProgressiveDisplay, InputSize(),
+ nextOutputRow) >= 0);
+ MOZ_ASSERT(HaeberliOutputUntilRow(mPass, mProgressiveDisplay, InputSize(),
+ nextOutputRow) <= InputSize().height);
+ MOZ_ASSERT(HaeberliOutputUntilRow(mPass, mProgressiveDisplay, InputSize(),
+ nextOutputRow) > nextOutputRow);
+
+ int32_t nextHaeberliOutputRow =
+ HaeberliOutputStartRow(mPass, mProgressiveDisplay, nextOutputRow);
+
+ // Copy rows from the buffer until we reach the desired output row.
+ if (advancedPass) {
+ OutputRows(0, nextHaeberliOutputRow);
+ } else {
+ OutputRows(HaeberliOutputUntilRow(mPass, mProgressiveDisplay, InputSize(),
+ mOutputRow),
+ nextHaeberliOutputRow);
+ }
+
+ // Update our position within the buffer.
+ mInputRow++;
+ mOutputRow = nextOutputRow;
+
+ // We'll actually write to the first Haeberli output row, then copy it until
+ // we reach the last Haeberli output row. The assertions above make sure
+ // this always includes mOutputRow.
+ return GetRowPointer(nextHaeberliOutputRow);
+ }
+
+ private:
+ static uint32_t InterlaceOffset(uint32_t aPass) {
+ MOZ_ASSERT(aPass < 4, "Invalid pass");
+ static const uint8_t offset[] = {0, 4, 2, 1};
+ return offset[aPass];
+ }
+
+ static uint32_t InterlaceStride(uint32_t aPass) {
+ MOZ_ASSERT(aPass < 4, "Invalid pass");
+ static const uint8_t stride[] = {8, 8, 4, 2};
+ return stride[aPass];
+ }
+
+ static int32_t HaeberliOutputStartRow(uint32_t aPass,
+ bool aProgressiveDisplay,
+ int32_t aOutputRow) {
+ MOZ_ASSERT(aPass < 4, "Invalid pass");
+ static const uint8_t firstRowOffset[] = {3, 1, 0, 0};
+
+ if (aProgressiveDisplay) {
+ return std::max(aOutputRow - firstRowOffset[aPass], 0);
+ } else {
+ return aOutputRow;
+ }
+ }
+
+ static int32_t HaeberliOutputUntilRow(uint32_t aPass,
+ bool aProgressiveDisplay,
+ const gfx::IntSize& aInputSize,
+ int32_t aOutputRow) {
+ MOZ_ASSERT(aPass < 4, "Invalid pass");
+ static const uint8_t lastRowOffset[] = {4, 2, 1, 0};
+
+ if (aProgressiveDisplay) {
+ return std::min(aOutputRow + lastRowOffset[aPass],
+ aInputSize.height - 1) +
+ 1; // Add one because this is an open interval on the right.
+ } else {
+ return aOutputRow + 1;
+ }
+ }
+
+ void DuplicateRows(int32_t aStart, int32_t aUntil) {
+ MOZ_ASSERT(aStart >= 0);
+ MOZ_ASSERT(aUntil >= 0);
+
+ if (aUntil <= aStart || aStart >= InputSize().height) {
+ return;
+ }
+
+ // The source row is the first row in the range.
+ const uint8_t* sourceRowPointer = GetRowPointer(aStart);
+
+ // We duplicate the source row into each subsequent row in the range.
+ for (int32_t destRow = aStart + 1; destRow < aUntil; ++destRow) {
+ uint8_t* destRowPointer = GetRowPointer(destRow);
+ memcpy(destRowPointer, sourceRowPointer,
+ InputSize().width * sizeof(PixelType));
+ }
+ }
+
+ void OutputRows(int32_t aStart, int32_t aUntil) {
+ MOZ_ASSERT(aStart >= 0);
+ MOZ_ASSERT(aUntil >= 0);
+
+ if (aUntil <= aStart || aStart >= InputSize().height) {
+ return;
+ }
+
+ for (int32_t rowToOutput = aStart; rowToOutput < aUntil; ++rowToOutput) {
+ mNext.WriteBuffer(
+ reinterpret_cast<PixelType*>(GetRowPointer(rowToOutput)));
+ }
+ }
+
+ uint8_t* GetRowPointer(uint32_t aRow) const {
+#ifdef DEBUG
+ uint64_t offset64 = uint64_t(aRow) * uint64_t(InputSize().width) *
+ uint64_t(sizeof(PixelType));
+ uint64_t bufferLength = uint64_t(InputSize().width) *
+ uint64_t(InputSize().height) *
+ uint64_t(sizeof(PixelType));
+ MOZ_ASSERT(offset64 < bufferLength, "Start of row is outside of image");
+ MOZ_ASSERT(
+ offset64 + uint64_t(InputSize().width) * uint64_t(sizeof(PixelType)) <=
+ bufferLength,
+ "End of row is outside of image");
+#endif
+ uint32_t offset = aRow * InputSize().width * sizeof(PixelType);
+ return mBuffer.get() + offset;
+ }
+
+ Next mNext; /// The next SurfaceFilter in the chain.
+
+ UniquePtr<uint8_t[]> mBuffer; /// The buffer used to store reordered rows.
+ int32_t mInputRow; /// The current row we're reading. (0-indexed)
+ int32_t mOutputRow; /// The current row we're writing. (0-indexed)
+ uint8_t mPass; /// Which pass we're on. (0-indexed)
+ bool mProgressiveDisplay; /// If true, duplicate rows to optimize for
+ /// progressive display.
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// BlendAnimationFilter
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename Next>
+class BlendAnimationFilter;
+
+/**
+ * A configuration struct for BlendAnimationFilter.
+ */
+struct BlendAnimationConfig {
+ template <typename Next>
+ using Filter = BlendAnimationFilter<Next>;
+ Decoder* mDecoder; /// The decoder producing the animation.
+};
+
+/**
+ * BlendAnimationFilter turns a partial image as part of an animation into a
+ * complete frame given its frame rect, blend method, and the base frame's
+ * data buffer, frame rect and disposal method. Any excess data caused by a
+ * frame rect not being contained by the output size will be discarded.
+ *
+ * The base frame is an already produced complete frame from the animation.
+ * It may be any previous frame depending on the disposal method, although
+ * most often it will be the immediate previous frame to the current we are
+ * generating.
+ *
+ * The 'Next' template parameter specifies the next filter in the chain.
+ */
+template <typename Next>
+class BlendAnimationFilter final : public SurfaceFilter {
+ public:
+ BlendAnimationFilter()
+ : mRow(0),
+ mRowLength(0),
+ mRecycleRow(0),
+ mRecycleRowMost(0),
+ mRecycleRowOffset(0),
+ mRecycleRowLength(0),
+ mClearRow(0),
+ mClearRowMost(0),
+ mClearPrefixLength(0),
+ mClearInfixOffset(0),
+ mClearInfixLength(0),
+ mClearPostfixOffset(0),
+ mClearPostfixLength(0),
+ mOverProc(nullptr),
+ mBaseFrameStartPtr(nullptr),
+ mBaseFrameRowPtr(nullptr) {}
+
+ template <typename... Rest>
+ nsresult Configure(const BlendAnimationConfig& aConfig,
+ const Rest&... aRest) {
+ nsresult rv = mNext.Configure(aRest...);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ imgFrame* currentFrame = aConfig.mDecoder->GetCurrentFrame();
+ if (!currentFrame) {
+ MOZ_ASSERT_UNREACHABLE("Decoder must have current frame!");
+ return NS_ERROR_FAILURE;
+ }
+
+ mFrameRect = mUnclampedFrameRect = currentFrame->GetBlendRect();
+ gfx::IntSize outputSize = mNext.InputSize();
+ mRowLength = outputSize.width * sizeof(uint32_t);
+
+ // Forbid frame rects with negative size.
+ if (mUnclampedFrameRect.width < 0 || mUnclampedFrameRect.height < 0) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Clamp mFrameRect to the output size.
+ gfx::IntRect outputRect(0, 0, outputSize.width, outputSize.height);
+ mFrameRect = mFrameRect.Intersect(outputRect);
+ bool fullFrame = outputRect.IsEqualEdges(mFrameRect);
+
+ // If there's no intersection, |mFrameRect| will be an empty rect positioned
+ // at the maximum of |inputRect|'s and |aFrameRect|'s coordinates, which is
+ // not what we want. Force it to (0, 0) sized 0 x 0 in that case.
+ if (mFrameRect.IsEmpty()) {
+ mFrameRect.SetRect(0, 0, 0, 0);
+ }
+
+ BlendMethod blendMethod = currentFrame->GetBlendMethod();
+ switch (blendMethod) {
+ default:
+ blendMethod = BlendMethod::SOURCE;
+ MOZ_FALLTHROUGH_ASSERT("Unexpected blend method!");
+ case BlendMethod::SOURCE:
+ // Default, overwrites base frame data (if any) with new.
+ break;
+ case BlendMethod::OVER:
+ // OVER only has an impact on the output if we have new data to blend
+ // with.
+ if (mFrameRect.IsEmpty()) {
+ blendMethod = BlendMethod::SOURCE;
+ }
+ break;
+ }
+
+ // Determine what we need to clear and what we need to copy. If this frame
+ // is a full frame and uses source blending, there is no need to consider
+ // the disposal method of the previous frame.
+ gfx::IntRect dirtyRect(outputRect);
+ gfx::IntRect clearRect;
+ if (!fullFrame || blendMethod != BlendMethod::SOURCE) {
+ const RawAccessFrameRef& restoreFrame =
+ aConfig.mDecoder->GetRestoreFrameRef();
+ if (restoreFrame) {
+ MOZ_ASSERT(restoreFrame->GetSize() == outputSize);
+ MOZ_ASSERT(restoreFrame->IsFinished());
+
+ // We can safely use this pointer without holding a RawAccessFrameRef
+ // because the decoder will keep it alive for us.
+ mBaseFrameStartPtr = restoreFrame.Data();
+ MOZ_ASSERT(mBaseFrameStartPtr);
+
+ gfx::IntRect restoreBlendRect = restoreFrame->GetBoundedBlendRect();
+ gfx::IntRect restoreDirtyRect = aConfig.mDecoder->GetRestoreDirtyRect();
+ switch (restoreFrame->GetDisposalMethod()) {
+ default:
+ case DisposalMethod::RESTORE_PREVIOUS:
+ MOZ_FALLTHROUGH_ASSERT("Unexpected DisposalMethod");
+ case DisposalMethod::NOT_SPECIFIED:
+ case DisposalMethod::KEEP:
+ dirtyRect = mFrameRect.Union(restoreDirtyRect);
+ break;
+ case DisposalMethod::CLEAR:
+ // We only need to clear if the rect is outside the frame rect (i.e.
+ // overwrites a non-overlapping area) or the blend method may cause
+ // us to combine old data and new.
+ if (!mFrameRect.Contains(restoreBlendRect) ||
+ blendMethod == BlendMethod::OVER) {
+ clearRect = restoreBlendRect;
+ }
+
+ // If we are clearing the whole frame, we do not need to retain a
+ // reference to the base frame buffer.
+ if (outputRect.IsEqualEdges(clearRect)) {
+ mBaseFrameStartPtr = nullptr;
+ } else {
+ dirtyRect = mFrameRect.Union(restoreDirtyRect).Union(clearRect);
+ }
+ break;
+ }
+ } else if (!fullFrame) {
+ // This must be the first frame, clear everything.
+ clearRect = outputRect;
+ }
+ }
+
+ // We may be able to reuse parts of our underlying buffer that we are
+ // writing the new frame to. The recycle rect gives us the invalidation
+ // region which needs to be copied from the restore frame.
+ const gfx::IntRect& recycleRect = aConfig.mDecoder->GetRecycleRect();
+ mRecycleRow = recycleRect.y;
+ mRecycleRowMost = recycleRect.YMost();
+ mRecycleRowOffset = recycleRect.x * sizeof(uint32_t);
+ mRecycleRowLength = recycleRect.width * sizeof(uint32_t);
+
+ if (!clearRect.IsEmpty()) {
+ // The clear rect interacts with the recycle rect because we need to copy
+ // the prefix and postfix data from the base frame. The one thing we do
+ // know is that the infix area is always cleared explicitly.
+ mClearRow = clearRect.y;
+ mClearRowMost = clearRect.YMost();
+ mClearInfixOffset = clearRect.x * sizeof(uint32_t);
+ mClearInfixLength = clearRect.width * sizeof(uint32_t);
+
+ // The recycle row offset is where we need to begin copying base frame
+ // data for a row. If this offset begins after or at the clear infix
+ // offset, then there is no prefix data at all.
+ if (mClearInfixOffset > mRecycleRowOffset) {
+ mClearPrefixLength = mClearInfixOffset - mRecycleRowOffset;
+ }
+
+ // Similar to the prefix, if the postfix offset begins outside the recycle
+ // rect, then we know we already have all the data we need.
+ mClearPostfixOffset = mClearInfixOffset + mClearInfixLength;
+ size_t recycleRowEndOffset = mRecycleRowOffset + mRecycleRowLength;
+ if (mClearPostfixOffset < recycleRowEndOffset) {
+ mClearPostfixLength = recycleRowEndOffset - mClearPostfixOffset;
+ }
+ }
+
+ // The dirty rect, or delta between the current frame and the previous frame
+ // (chronologically, not necessarily the restore frame) is the last
+ // animation parameter we need to initialize the new frame with.
+ currentFrame->SetDirtyRect(dirtyRect);
+
+ if (!mBaseFrameStartPtr) {
+ // Switch to SOURCE if no base frame to ensure we don't allocate an
+ // intermediate buffer below. OVER does nothing without the base frame
+ // data.
+ blendMethod = BlendMethod::SOURCE;
+ }
+
+ // Skia provides arch-specific accelerated methods to perform blending.
+ // Note that this is an internal Skia API and may be prone to change,
+ // but we avoid the overhead of setting up Skia objects.
+ if (blendMethod == BlendMethod::OVER) {
+ mOverProc = SkBlitRow::Factory32(SkBlitRow::kSrcPixelAlpha_Flag32);
+ MOZ_ASSERT(mOverProc);
+ }
+
+ // We don't need an intermediate buffer unless the unclamped frame rect
+ // width is larger than the clamped frame rect width. In that case, the
+ // caller will end up writing data that won't end up in the final image at
+ // all, and we'll need a buffer to give that data a place to go.
+ if (mFrameRect.width < mUnclampedFrameRect.width || mOverProc) {
+ mBuffer.reset(new (fallible)
+ uint8_t[mUnclampedFrameRect.width * sizeof(uint32_t)]);
+ if (MOZ_UNLIKELY(!mBuffer)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ memset(mBuffer.get(), 0, mUnclampedFrameRect.width * sizeof(uint32_t));
+ }
+
+ ConfigureFilter(mUnclampedFrameRect.Size(), sizeof(uint32_t));
+ return NS_OK;
+ }
+
+ Maybe<SurfaceInvalidRect> TakeInvalidRect() override {
+ return mNext.TakeInvalidRect();
+ }
+
+ protected:
+ uint8_t* DoResetToFirstRow() override {
+ uint8_t* rowPtr = mNext.ResetToFirstRow();
+ if (rowPtr == nullptr) {
+ mRow = mFrameRect.YMost();
+ return nullptr;
+ }
+
+ mRow = 0;
+ mBaseFrameRowPtr = mBaseFrameStartPtr;
+
+ while (mRow < mFrameRect.y) {
+ WriteBaseFrameRow();
+ AdvanceRowOutsideFrameRect();
+ }
+
+ // We're at the beginning of the frame rect now, so return if we're either
+ // ready for input or we're already done.
+ rowPtr = mBuffer ? mBuffer.get() : mNext.CurrentRowPointer();
+ if (!mFrameRect.IsEmpty() || rowPtr == nullptr) {
+ // Note that the pointer we're returning is for the next row we're
+ // actually going to write to, but we may discard writes before that point
+ // if mRow < mFrameRect.y.
+ mRow = mUnclampedFrameRect.y;
+ WriteBaseFrameRow();
+ return AdjustRowPointer(rowPtr);
+ }
+
+ // We've finished the region specified by the frame rect, but the frame rect
+ // is empty, so we need to output the rest of the image immediately. Advance
+ // to the end of the next pipeline stage's buffer, outputting rows that are
+ // copied from the base frame and/or cleared.
+ WriteBaseFrameRowsUntilComplete();
+
+ mRow = mFrameRect.YMost();
+ return nullptr; // We're done.
+ }
+
+ uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
+ CopyInputRow(aInputRow);
+ return DoAdvanceRow();
+ }
+
+ uint8_t* DoAdvanceRow() override {
+ uint8_t* rowPtr = nullptr;
+
+ const int32_t currentRow = mRow;
+ mRow++;
+
+ // The unclamped frame rect has a negative offset which means -y rows from
+ // the decoder need to be discarded before we advance properly.
+ if (currentRow >= 0 && mBaseFrameRowPtr) {
+ mBaseFrameRowPtr += mRowLength;
+ }
+
+ if (currentRow < mFrameRect.y) {
+ // This row is outside of the frame rect, so just drop it on the floor.
+ rowPtr = mBuffer ? mBuffer.get() : mNext.CurrentRowPointer();
+ return AdjustRowPointer(rowPtr);
+ } else if (NS_WARN_IF(currentRow >= mFrameRect.YMost())) {
+ return nullptr;
+ }
+
+ // If we had to buffer, merge the data into the row. Otherwise we had the
+ // decoder write directly to the next stage's buffer.
+ if (mBuffer) {
+ int32_t width = mFrameRect.width;
+ uint32_t* dst = reinterpret_cast<uint32_t*>(mNext.CurrentRowPointer());
+ uint32_t* src = reinterpret_cast<uint32_t*>(mBuffer.get()) -
+ std::min(mUnclampedFrameRect.x, 0);
+ dst += mFrameRect.x;
+ if (mOverProc) {
+ mOverProc(dst, src, width, 0xFF);
+ } else {
+ memcpy(dst, src, width * sizeof(uint32_t));
+ }
+ rowPtr = mNext.AdvanceRow() ? mBuffer.get() : nullptr;
+ } else {
+ MOZ_ASSERT(!mOverProc);
+ rowPtr = mNext.AdvanceRow();
+ }
+
+ // If there's still more data coming or we're already done, just adjust the
+ // pointer and return.
+ if (mRow < mFrameRect.YMost() || rowPtr == nullptr) {
+ WriteBaseFrameRow();
+ return AdjustRowPointer(rowPtr);
+ }
+
+ // We've finished the region specified by the frame rect. Advance to the end
+ // of the next pipeline stage's buffer, outputting rows that are copied from
+ // the base frame and/or cleared.
+ WriteBaseFrameRowsUntilComplete();
+
+ return nullptr; // We're done.
+ }
+
+ private:
+ void WriteBaseFrameRowsUntilComplete() {
+ do {
+ WriteBaseFrameRow();
+ } while (AdvanceRowOutsideFrameRect());
+ }
+
+ void WriteBaseFrameRow() {
+ uint8_t* dest = mNext.CurrentRowPointer();
+ if (!dest) {
+ return;
+ }
+
+ // No need to copy pixels from the base frame for rows that will not change
+ // between the recycled frame and the new frame.
+ bool needBaseFrame = mRow >= mRecycleRow && mRow < mRecycleRowMost;
+
+ if (!mBaseFrameRowPtr) {
+ // No base frame, so we are clearing everything.
+ if (needBaseFrame) {
+ memset(dest + mRecycleRowOffset, 0, mRecycleRowLength);
+ }
+ } else if (mClearRow <= mRow && mClearRowMost > mRow) {
+ // We have a base frame, but we are inside the area to be cleared.
+ // Only copy the data we need from the source.
+ if (needBaseFrame) {
+ memcpy(dest + mRecycleRowOffset, mBaseFrameRowPtr + mRecycleRowOffset,
+ mClearPrefixLength);
+ memcpy(dest + mClearPostfixOffset,
+ mBaseFrameRowPtr + mClearPostfixOffset, mClearPostfixLength);
+ }
+ memset(dest + mClearInfixOffset, 0, mClearInfixLength);
+ } else if (needBaseFrame) {
+ memcpy(dest + mRecycleRowOffset, mBaseFrameRowPtr + mRecycleRowOffset,
+ mRecycleRowLength);
+ }
+ }
+
+ bool AdvanceRowOutsideFrameRect() {
+ // The unclamped frame rect may have a negative offset however we should
+ // never be advancing the row via this path (otherwise mBaseFrameRowPtr
+ // will be wrong.
+ MOZ_ASSERT(mRow >= 0);
+ MOZ_ASSERT(mRow < mFrameRect.y || mRow >= mFrameRect.YMost());
+
+ mRow++;
+ if (mBaseFrameRowPtr) {
+ mBaseFrameRowPtr += mRowLength;
+ }
+
+ return mNext.AdvanceRow() != nullptr;
+ }
+
+ uint8_t* AdjustRowPointer(uint8_t* aNextRowPointer) const {
+ if (mBuffer) {
+ MOZ_ASSERT(aNextRowPointer == mBuffer.get() ||
+ aNextRowPointer == nullptr);
+ return aNextRowPointer; // No adjustment needed for an intermediate
+ // buffer.
+ }
+
+ if (mFrameRect.IsEmpty() || mRow >= mFrameRect.YMost() ||
+ aNextRowPointer == nullptr) {
+ return nullptr; // Nothing left to write.
+ }
+
+ MOZ_ASSERT(!mOverProc);
+ return aNextRowPointer + mFrameRect.x * sizeof(uint32_t);
+ }
+
+ Next mNext; /// The next SurfaceFilter in the chain.
+
+ gfx::IntRect mFrameRect; /// The surface subrect which contains data,
+ /// clamped to the image size.
+ gfx::IntRect mUnclampedFrameRect; /// The frame rect before clamping.
+ UniquePtr<uint8_t[]> mBuffer; /// The intermediate buffer, if one is
+ /// necessary because the frame rect width
+ /// is larger than the image's logical width.
+ int32_t mRow; /// The row in unclamped frame rect space
+ /// that we're currently writing.
+ size_t mRowLength; /// Length in bytes of a row that is the input
+ /// for the next filter.
+ int32_t mRecycleRow; /// The starting row of the recycle rect.
+ int32_t mRecycleRowMost; /// The ending row of the recycle rect.
+ size_t mRecycleRowOffset; /// Row offset in bytes of the recycle rect.
+ size_t mRecycleRowLength; /// Row length in bytes of the recycle rect.
+
+ /// The frame area to clear before blending the current frame.
+ int32_t mClearRow; /// The starting row of the clear rect.
+ int32_t mClearRowMost; /// The ending row of the clear rect.
+ size_t mClearPrefixLength; /// Row length in bytes of clear prefix.
+ size_t mClearInfixOffset; /// Row offset in bytes of clear area.
+ size_t mClearInfixLength; /// Row length in bytes of clear area.
+ size_t mClearPostfixOffset; /// Row offset in bytes of clear postfix.
+ size_t mClearPostfixLength; /// Row length in bytes of clear postfix.
+
+ SkBlitRow::Proc32 mOverProc; /// Function pointer to perform over blending.
+ const uint8_t*
+ mBaseFrameStartPtr; /// Starting row pointer to the base frame
+ /// data from which we copy pixel data from.
+ const uint8_t* mBaseFrameRowPtr; /// Current row pointer to the base frame
+ /// data.
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// RemoveFrameRectFilter
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename Next>
+class RemoveFrameRectFilter;
+
+/**
+ * A configuration struct for RemoveFrameRectFilter.
+ */
+struct RemoveFrameRectConfig {
+ template <typename Next>
+ using Filter = RemoveFrameRectFilter<Next>;
+ gfx::IntRect mFrameRect; /// The surface subrect which contains data.
+};
+
+/**
+ * RemoveFrameRectFilter turns an image with a frame rect that does not match
+ * its logical size into an image with no frame rect. It does this by writing
+ * transparent pixels into any padding regions and throwing away excess data.
+ *
+ * The 'Next' template parameter specifies the next filter in the chain.
+ */
+template <typename Next>
+class RemoveFrameRectFilter final : public SurfaceFilter {
+ public:
+ RemoveFrameRectFilter() : mRow(0) {}
+
+ template <typename... Rest>
+ nsresult Configure(const RemoveFrameRectConfig& aConfig,
+ const Rest&... aRest) {
+ nsresult rv = mNext.Configure(aRest...);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ mFrameRect = mUnclampedFrameRect = aConfig.mFrameRect;
+ gfx::IntSize outputSize = mNext.InputSize();
+
+ // Forbid frame rects with negative size.
+ if (aConfig.mFrameRect.Width() < 0 || aConfig.mFrameRect.Height() < 0) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // Clamp mFrameRect to the output size.
+ gfx::IntRect outputRect(0, 0, outputSize.width, outputSize.height);
+ mFrameRect = mFrameRect.Intersect(outputRect);
+
+ // If there's no intersection, |mFrameRect| will be an empty rect positioned
+ // at the maximum of |inputRect|'s and |aFrameRect|'s coordinates, which is
+ // not what we want. Force it to (0, 0) in that case.
+ if (mFrameRect.IsEmpty()) {
+ mFrameRect.MoveTo(0, 0);
+ }
+
+ // We don't need an intermediate buffer unless the unclamped frame rect
+ // width is larger than the clamped frame rect width. In that case, the
+ // caller will end up writing data that won't end up in the final image at
+ // all, and we'll need a buffer to give that data a place to go.
+ if (mFrameRect.Width() < mUnclampedFrameRect.Width()) {
+ mBuffer.reset(new (
+ fallible) uint8_t[mUnclampedFrameRect.Width() * sizeof(uint32_t)]);
+ if (MOZ_UNLIKELY(!mBuffer)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ memset(mBuffer.get(), 0, mUnclampedFrameRect.Width() * sizeof(uint32_t));
+ }
+
+ ConfigureFilter(mUnclampedFrameRect.Size(), sizeof(uint32_t));
+ return NS_OK;
+ }
+
+ Maybe<SurfaceInvalidRect> TakeInvalidRect() override {
+ return mNext.TakeInvalidRect();
+ }
+
+ protected:
+ uint8_t* DoResetToFirstRow() override {
+ uint8_t* rowPtr = mNext.ResetToFirstRow();
+ if (rowPtr == nullptr) {
+ mRow = mFrameRect.YMost();
+ return nullptr;
+ }
+
+ mRow = mUnclampedFrameRect.Y();
+
+ // Advance the next pipeline stage to the beginning of the frame rect,
+ // outputting blank rows.
+ if (mFrameRect.Y() > 0) {
+ for (int32_t rowToOutput = 0; rowToOutput < mFrameRect.Y();
+ ++rowToOutput) {
+ mNext.WriteEmptyRow();
+ }
+ }
+
+ // We're at the beginning of the frame rect now, so return if we're either
+ // ready for input or we're already done.
+ rowPtr = mBuffer ? mBuffer.get() : mNext.CurrentRowPointer();
+ if (!mFrameRect.IsEmpty() || rowPtr == nullptr) {
+ // Note that the pointer we're returning is for the next row we're
+ // actually going to write to, but we may discard writes before that point
+ // if mRow < mFrameRect.y.
+ return AdjustRowPointer(rowPtr);
+ }
+
+ // We've finished the region specified by the frame rect, but the frame rect
+ // is empty, so we need to output the rest of the image immediately. Advance
+ // to the end of the next pipeline stage's buffer, outputting blank rows.
+ while (mNext.WriteEmptyRow() == WriteState::NEED_MORE_DATA) {
+ }
+
+ mRow = mFrameRect.YMost();
+ return nullptr; // We're done.
+ }
+
+ uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
+ CopyInputRow(aInputRow);
+ return DoAdvanceRow();
+ }
+
+ uint8_t* DoAdvanceRow() override {
+ uint8_t* rowPtr = nullptr;
+
+ const int32_t currentRow = mRow;
+ mRow++;
+
+ if (currentRow < mFrameRect.Y()) {
+ // This row is outside of the frame rect, so just drop it on the floor.
+ rowPtr = mBuffer ? mBuffer.get() : mNext.CurrentRowPointer();
+ return AdjustRowPointer(rowPtr);
+ } else if (currentRow >= mFrameRect.YMost()) {
+ NS_WARNING("RemoveFrameRectFilter: Advancing past end of frame rect");
+ return nullptr;
+ }
+
+ // If we had to buffer, copy the data. Otherwise, just advance the row.
+ if (mBuffer) {
+ // We write from the beginning of the buffer unless
+ // |mUnclampedFrameRect.x| is negative; if that's the case, we have to
+ // skip the portion of the unclamped frame rect that's outside the row.
+ uint32_t* source = reinterpret_cast<uint32_t*>(mBuffer.get()) -
+ std::min(mUnclampedFrameRect.X(), 0);
+
+ // We write |mFrameRect.width| columns starting at |mFrameRect.x|; we've
+ // already clamped these values to the size of the output, so we don't
+ // have to worry about bounds checking here (though WriteBuffer() will do
+ // it for us in any case).
+ WriteState state =
+ mNext.WriteBuffer(source, mFrameRect.X(), mFrameRect.Width());
+
+ rowPtr = state == WriteState::NEED_MORE_DATA ? mBuffer.get() : nullptr;
+ } else {
+ rowPtr = mNext.AdvanceRow();
+ }
+
+ // If there's still more data coming or we're already done, just adjust the
+ // pointer and return.
+ if (mRow < mFrameRect.YMost() || rowPtr == nullptr) {
+ return AdjustRowPointer(rowPtr);
+ }
+
+ // We've finished the region specified by the frame rect. Advance to the end
+ // of the next pipeline stage's buffer, outputting blank rows.
+ while (mNext.WriteEmptyRow() == WriteState::NEED_MORE_DATA) {
+ }
+
+ mRow = mFrameRect.YMost();
+ return nullptr; // We're done.
+ }
+
+ private:
+ uint8_t* AdjustRowPointer(uint8_t* aNextRowPointer) const {
+ if (mBuffer) {
+ MOZ_ASSERT(aNextRowPointer == mBuffer.get() ||
+ aNextRowPointer == nullptr);
+ return aNextRowPointer; // No adjustment needed for an intermediate
+ // buffer.
+ }
+
+ if (mFrameRect.IsEmpty() || mRow >= mFrameRect.YMost() ||
+ aNextRowPointer == nullptr) {
+ return nullptr; // Nothing left to write.
+ }
+
+ return aNextRowPointer + mFrameRect.X() * sizeof(uint32_t);
+ }
+
+ Next mNext; /// The next SurfaceFilter in the chain.
+
+ gfx::IntRect mFrameRect; /// The surface subrect which contains data,
+ /// clamped to the image size.
+ gfx::IntRect mUnclampedFrameRect; /// The frame rect before clamping.
+ UniquePtr<uint8_t[]> mBuffer; /// The intermediate buffer, if one is
+ /// necessary because the frame rect width
+ /// is larger than the image's logical width.
+ int32_t mRow; /// The row in unclamped frame rect space
+ /// that we're currently writing.
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// ADAM7InterpolatingFilter
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename Next>
+class ADAM7InterpolatingFilter;
+
+/**
+ * A configuration struct for ADAM7InterpolatingFilter.
+ */
+struct ADAM7InterpolatingConfig {
+ template <typename Next>
+ using Filter = ADAM7InterpolatingFilter<Next>;
+};
+
+/**
+ * ADAM7InterpolatingFilter performs bilinear interpolation over an ADAM7
+ * interlaced image.
+ *
+ * ADAM7 breaks up the image into 8x8 blocks. On each of the 7 passes, a new set
+ * of pixels in each block receives their final values, according to the
+ * following pattern:
+ *
+ * 1 6 4 6 2 6 4 6
+ * 7 7 7 7 7 7 7 7
+ * 5 6 5 6 5 6 5 6
+ * 7 7 7 7 7 7 7 7
+ * 3 6 4 6 3 6 4 6
+ * 7 7 7 7 7 7 7 7
+ * 5 6 5 6 5 6 5 6
+ * 7 7 7 7 7 7 7 7
+ *
+ * When rendering the pixels that have not yet received their final values, we
+ * can get much better intermediate results if we interpolate between
+ * the pixels we *have* gotten so far. This filter performs bilinear
+ * interpolation by first performing linear interpolation horizontally for each
+ * "important" row (which we'll define as a row that has received any pixels
+ * with final values at all) and then performing linear interpolation vertically
+ * to produce pixel values for rows which aren't important on the current pass.
+ *
+ * Note that this filter totally ignores the data which is written to rows which
+ * aren't important on the current pass! It's fine to write nothing at all for
+ * these rows, although doing so won't cause any harm.
+ *
+ * XXX(seth): In bug 1280552 we'll add a SIMD implementation for this filter.
+ *
+ * The 'Next' template parameter specifies the next filter in the chain.
+ */
+template <typename Next>
+class ADAM7InterpolatingFilter final : public SurfaceFilter {
+ public:
+ ADAM7InterpolatingFilter()
+ : mPass(0) // The current pass, in the range 1..7. Starts at 0 so that
+ // DoResetToFirstRow() doesn't have to special case the first
+ // pass.
+ ,
+ mRow(0) {}
+
+ template <typename... Rest>
+ nsresult Configure(const ADAM7InterpolatingConfig& aConfig,
+ const Rest&... aRest) {
+ nsresult rv = mNext.Configure(aRest...);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ // We have two intermediate buffers, one for the previous row with final
+ // pixel values and one for the row that the previous filter in the chain is
+ // currently writing to.
+ size_t inputWidthInBytes = mNext.InputSize().width * sizeof(uint32_t);
+ mPreviousRow.reset(new (fallible) uint8_t[inputWidthInBytes]);
+ if (MOZ_UNLIKELY(!mPreviousRow)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ mCurrentRow.reset(new (fallible) uint8_t[inputWidthInBytes]);
+ if (MOZ_UNLIKELY(!mCurrentRow)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ memset(mPreviousRow.get(), 0, inputWidthInBytes);
+ memset(mCurrentRow.get(), 0, inputWidthInBytes);
+
+ ConfigureFilter(mNext.InputSize(), sizeof(uint32_t));
+ return NS_OK;
+ }
+
+ Maybe<SurfaceInvalidRect> TakeInvalidRect() override {
+ return mNext.TakeInvalidRect();
+ }
+
+ protected:
+ uint8_t* DoResetToFirstRow() override {
+ mRow = 0;
+ mPass = std::min(mPass + 1, 7);
+
+ uint8_t* rowPtr = mNext.ResetToFirstRow();
+ if (mPass == 7) {
+ // Short circuit this filter on the final pass, since all pixels have
+ // their final values at that point.
+ return rowPtr;
+ }
+
+ return mCurrentRow.get();
+ }
+
+ uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
+ CopyInputRow(aInputRow);
+ return DoAdvanceRow();
+ }
+
+ uint8_t* DoAdvanceRow() override {
+ MOZ_ASSERT(0 < mPass && mPass <= 7, "Invalid pass");
+
+ int32_t currentRow = mRow;
+ ++mRow;
+
+ if (mPass == 7) {
+ // On the final pass we short circuit this filter totally.
+ return mNext.AdvanceRow();
+ }
+
+ const int32_t lastImportantRow =
+ LastImportantRow(InputSize().height, mPass);
+ if (currentRow > lastImportantRow) {
+ return nullptr; // This pass is already complete.
+ }
+
+ if (!IsImportantRow(currentRow, mPass)) {
+ // We just ignore whatever the caller gives us for these rows. We'll
+ // interpolate them in later.
+ return mCurrentRow.get();
+ }
+
+ // This is an important row. We need to perform horizontal interpolation for
+ // these rows.
+ InterpolateHorizontally(mCurrentRow.get(), InputSize().width, mPass);
+
+ // Interpolate vertically between the previous important row and the current
+ // important row. We skip this if the current row is 0 (which is always an
+ // important row), because in that case there is no previous important row
+ // to interpolate with.
+ if (currentRow != 0) {
+ InterpolateVertically(mPreviousRow.get(), mCurrentRow.get(), mPass,
+ mNext);
+ }
+
+ // Write out the current row itself, which, being an important row, does not
+ // need vertical interpolation.
+ uint32_t* currentRowAsPixels =
+ reinterpret_cast<uint32_t*>(mCurrentRow.get());
+ mNext.WriteBuffer(currentRowAsPixels);
+
+ if (currentRow == lastImportantRow) {
+ // This is the last important row, which completes this pass. Note that
+ // for very small images, this may be the first row! Since there won't be
+ // another important row, there's nothing to interpolate with vertically,
+ // so we just duplicate this row until the end of the image.
+ while (mNext.WriteBuffer(currentRowAsPixels) ==
+ WriteState::NEED_MORE_DATA) {
+ }
+
+ // All of the remaining rows in the image were determined above, so we're
+ // done.
+ return nullptr;
+ }
+
+ // The current row is now the previous important row; save it.
+ std::swap(mPreviousRow, mCurrentRow);
+
+ MOZ_ASSERT(mRow < InputSize().height,
+ "Reached the end of the surface without "
+ "hitting the last important row?");
+
+ return mCurrentRow.get();
+ }
+
+ private:
+ static void InterpolateVertically(uint8_t* aPreviousRow, uint8_t* aCurrentRow,
+ uint8_t aPass, SurfaceFilter& aNext) {
+ const float* weights = InterpolationWeights(ImportantRowStride(aPass));
+
+ // We need to interpolate vertically to generate the rows between the
+ // previous important row and the next one. Recall that important rows are
+ // rows which contain at least some final pixels; see
+ // InterpolateHorizontally() for some additional explanation as to what that
+ // means. Note that we've already written out the previous important row, so
+ // we start the iteration at 1.
+ for (int32_t outRow = 1; outRow < ImportantRowStride(aPass); ++outRow) {
+ const float weight = weights[outRow];
+
+ // We iterate through the previous and current important row every time we
+ // write out an interpolated row, so we need to copy the pointers.
+ uint8_t* prevRowBytes = aPreviousRow;
+ uint8_t* currRowBytes = aCurrentRow;
+
+ // Write out the interpolated pixels. Interpolation is componentwise.
+ aNext.template WritePixelsToRow<uint32_t>([&] {
+ uint32_t pixel = 0;
+ auto* component = reinterpret_cast<uint8_t*>(&pixel);
+ *component++ =
+ InterpolateByte(*prevRowBytes++, *currRowBytes++, weight);
+ *component++ =
+ InterpolateByte(*prevRowBytes++, *currRowBytes++, weight);
+ *component++ =
+ InterpolateByte(*prevRowBytes++, *currRowBytes++, weight);
+ *component++ =
+ InterpolateByte(*prevRowBytes++, *currRowBytes++, weight);
+ return AsVariant(pixel);
+ });
+ }
+ }
+
+ static void InterpolateHorizontally(uint8_t* aRow, int32_t aWidth,
+ uint8_t aPass) {
+ // Collect the data we'll need to perform horizontal interpolation. The
+ // terminology here bears some explanation: a "final pixel" is a pixel which
+ // has received its final value. On each pass, a new set of pixels receives
+ // their final value; see the diagram above of the 8x8 pattern that ADAM7
+ // uses. Any pixel which hasn't received its final value on this pass
+ // derives its value from either horizontal or vertical interpolation
+ // instead.
+ const size_t finalPixelStride = FinalPixelStride(aPass);
+ const size_t finalPixelStrideBytes = finalPixelStride * sizeof(uint32_t);
+ const size_t lastFinalPixel = LastFinalPixel(aWidth, aPass);
+ const size_t lastFinalPixelBytes = lastFinalPixel * sizeof(uint32_t);
+ const float* weights = InterpolationWeights(finalPixelStride);
+
+ // Interpolate blocks of pixels which lie between two final pixels.
+ // Horizontal interpolation is done in place, as we'll need the results
+ // later when we vertically interpolate.
+ for (size_t blockBytes = 0; blockBytes < lastFinalPixelBytes;
+ blockBytes += finalPixelStrideBytes) {
+ uint8_t* finalPixelA = aRow + blockBytes;
+ uint8_t* finalPixelB = aRow + blockBytes + finalPixelStrideBytes;
+
+ MOZ_ASSERT(finalPixelA < aRow + aWidth * sizeof(uint32_t),
+ "Running off end of buffer");
+ MOZ_ASSERT(finalPixelB < aRow + aWidth * sizeof(uint32_t),
+ "Running off end of buffer");
+
+ // Interpolate the individual pixels componentwise. Note that we start
+ // iteration at 1 since we don't need to apply any interpolation to the
+ // first pixel in the block, which has its final value.
+ for (size_t pixelIndex = 1; pixelIndex < finalPixelStride; ++pixelIndex) {
+ const float weight = weights[pixelIndex];
+ uint8_t* pixel = aRow + blockBytes + pixelIndex * sizeof(uint32_t);
+
+ MOZ_ASSERT(pixel < aRow + aWidth * sizeof(uint32_t),
+ "Running off end of buffer");
+
+ for (size_t component = 0; component < sizeof(uint32_t); ++component) {
+ pixel[component] = InterpolateByte(finalPixelA[component],
+ finalPixelB[component], weight);
+ }
+ }
+ }
+
+ // For the pixels after the last final pixel in the row, there isn't a
+ // second final pixel to interpolate with, so just duplicate.
+ uint32_t* rowPixels = reinterpret_cast<uint32_t*>(aRow);
+ uint32_t pixelToDuplicate = rowPixels[lastFinalPixel];
+ for (int32_t pixelIndex = lastFinalPixel + 1; pixelIndex < aWidth;
+ ++pixelIndex) {
+ MOZ_ASSERT(pixelIndex < aWidth, "Running off end of buffer");
+ rowPixels[pixelIndex] = pixelToDuplicate;
+ }
+ }
+
+ static uint8_t InterpolateByte(uint8_t aByteA, uint8_t aByteB,
+ float aWeight) {
+ return uint8_t(aByteA * aWeight + aByteB * (1.0f - aWeight));
+ }
+
+ static int32_t ImportantRowStride(uint8_t aPass) {
+ MOZ_ASSERT(0 < aPass && aPass <= 7, "Invalid pass");
+
+ // The stride between important rows for each pass, with a dummy value for
+ // the nonexistent pass 0.
+ static int32_t strides[] = {1, 8, 8, 4, 4, 2, 2, 1};
+
+ return strides[aPass];
+ }
+
+ static bool IsImportantRow(int32_t aRow, uint8_t aPass) {
+ MOZ_ASSERT(aRow >= 0);
+
+ // Whether the row is important comes down to divisibility by the stride for
+ // this pass, which is always a power of 2, so we can check using a mask.
+ int32_t mask = ImportantRowStride(aPass) - 1;
+ return (aRow & mask) == 0;
+ }
+
+ static int32_t LastImportantRow(int32_t aHeight, uint8_t aPass) {
+ MOZ_ASSERT(aHeight > 0);
+
+ // We can find the last important row using the same mask trick as above.
+ int32_t lastRow = aHeight - 1;
+ int32_t mask = ImportantRowStride(aPass) - 1;
+ return lastRow - (lastRow & mask);
+ }
+
+ static size_t FinalPixelStride(uint8_t aPass) {
+ MOZ_ASSERT(0 < aPass && aPass <= 7, "Invalid pass");
+
+ // The stride between the final pixels in important rows for each pass, with
+ // a dummy value for the nonexistent pass 0.
+ static size_t strides[] = {1, 8, 4, 4, 2, 2, 1, 1};
+
+ return strides[aPass];
+ }
+
+ static size_t LastFinalPixel(int32_t aWidth, uint8_t aPass) {
+ MOZ_ASSERT(aWidth >= 0);
+
+ // Again, we can use the mask trick above to find the last important pixel.
+ int32_t lastColumn = aWidth - 1;
+ size_t mask = FinalPixelStride(aPass) - 1;
+ return lastColumn - (lastColumn & mask);
+ }
+
+ static const float* InterpolationWeights(int32_t aStride) {
+ // Precalculated interpolation weights. These are used to interpolate
+ // between final pixels or between important rows. Although no interpolation
+ // is actually applied to the previous final pixel or important row value,
+ // the arrays still start with 1.0f, which is always skipped, primarily
+ // because otherwise |stride1Weights| would have zero elements.
+ static float stride8Weights[] = {1.0f, 7 / 8.0f, 6 / 8.0f, 5 / 8.0f,
+ 4 / 8.0f, 3 / 8.0f, 2 / 8.0f, 1 / 8.0f};
+ static float stride4Weights[] = {1.0f, 3 / 4.0f, 2 / 4.0f, 1 / 4.0f};
+ static float stride2Weights[] = {1.0f, 1 / 2.0f};
+ static float stride1Weights[] = {1.0f};
+
+ switch (aStride) {
+ case 8:
+ return stride8Weights;
+ case 4:
+ return stride4Weights;
+ case 2:
+ return stride2Weights;
+ case 1:
+ return stride1Weights;
+ default:
+ MOZ_CRASH();
+ }
+ }
+
+ Next mNext; /// The next SurfaceFilter in the chain.
+
+ UniquePtr<uint8_t[]>
+ mPreviousRow; /// The last important row (i.e., row with
+ /// final pixel values) that got written to.
+ UniquePtr<uint8_t[]> mCurrentRow; /// The row that's being written to right
+ /// now.
+ uint8_t mPass; /// Which ADAM7 pass we're on. Valid passes
+ /// are 1..7 during processing and 0 prior
+ /// to configuration.
+ int32_t mRow; /// The row we're currently reading.
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_SurfaceFilters_h
diff --git a/image/SurfaceFlags.h b/image/SurfaceFlags.h
new file mode 100644
index 0000000000..a494ea15ff
--- /dev/null
+++ b/image/SurfaceFlags.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_SurfaceFlags_h
+#define mozilla_image_SurfaceFlags_h
+
+#include "imgIContainer.h"
+#include "mozilla/TypedEnumBits.h"
+
+namespace mozilla {
+namespace image {
+
+/**
+ * Flags that change the output a decoder generates. Because different
+ * combinations of these flags result in logically different surfaces, these
+ * flags must be taken into account in SurfaceCache lookups.
+ */
+enum class SurfaceFlags : uint8_t {
+ NO_PREMULTIPLY_ALPHA = 1 << 0,
+ NO_COLORSPACE_CONVERSION = 1 << 1,
+ TO_SRGB_COLORSPACE = 1 << 2,
+ RECORD_BLOB = 1 << 3,
+};
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SurfaceFlags)
+
+/**
+ * @return the default set of surface flags.
+ */
+inline SurfaceFlags DefaultSurfaceFlags() { return SurfaceFlags(); }
+
+/**
+ * Given a set of imgIContainer FLAG_* flags, returns a set of SurfaceFlags with
+ * the corresponding flags set.
+ */
+inline SurfaceFlags ToSurfaceFlags(uint32_t aFlags) {
+ SurfaceFlags flags = DefaultSurfaceFlags();
+ if (aFlags & imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA) {
+ flags |= SurfaceFlags::NO_PREMULTIPLY_ALPHA;
+ }
+ if (aFlags & imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION) {
+ flags |= SurfaceFlags::NO_COLORSPACE_CONVERSION;
+ }
+ if (aFlags & imgIContainer::FLAG_DECODE_TO_SRGB_COLORSPACE) {
+ flags |= SurfaceFlags::TO_SRGB_COLORSPACE;
+ }
+ if (aFlags & imgIContainer::FLAG_RECORD_BLOB) {
+ flags |= SurfaceFlags::RECORD_BLOB;
+ }
+ return flags;
+}
+
+/**
+ * Given a set of SurfaceFlags, returns a set of imgIContainer FLAG_* flags with
+ * the corresponding flags set.
+ */
+inline uint32_t FromSurfaceFlags(SurfaceFlags aFlags) {
+ uint32_t flags = imgIContainer::DECODE_FLAGS_DEFAULT;
+ if (aFlags & SurfaceFlags::NO_PREMULTIPLY_ALPHA) {
+ flags |= imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA;
+ }
+ if (aFlags & SurfaceFlags::NO_COLORSPACE_CONVERSION) {
+ flags |= imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION;
+ }
+ if (aFlags & SurfaceFlags::TO_SRGB_COLORSPACE) {
+ flags |= imgIContainer::FLAG_DECODE_TO_SRGB_COLORSPACE;
+ }
+ if (aFlags & SurfaceFlags::RECORD_BLOB) {
+ flags |= imgIContainer::FLAG_RECORD_BLOB;
+ }
+ return flags;
+}
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_SurfaceFlags_h
diff --git a/image/SurfacePipe.cpp b/image/SurfacePipe.cpp
new file mode 100644
index 0000000000..2e4a86daef
--- /dev/null
+++ b/image/SurfacePipe.cpp
@@ -0,0 +1,162 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SurfacePipe.h"
+
+#include <algorithm> // for min
+
+#include "Decoder.h"
+
+namespace mozilla {
+namespace image {
+
+using namespace gfx;
+
+using std::min;
+
+Maybe<SurfaceInvalidRect> AbstractSurfaceSink::TakeInvalidRect() {
+ if (mInvalidRect.IsEmpty()) {
+ return Nothing();
+ }
+
+ SurfaceInvalidRect invalidRect;
+ invalidRect.mInputSpaceRect = invalidRect.mOutputSpaceRect = mInvalidRect;
+
+ // Forget about the invalid rect we're returning.
+ mInvalidRect = OrientedIntRect();
+
+ return Some(invalidRect);
+}
+
+uint8_t* AbstractSurfaceSink::DoResetToFirstRow() {
+ mRow = 0;
+ return GetRowPointer();
+}
+
+uint8_t* SurfaceSink::DoAdvanceRowFromBuffer(const uint8_t* aInputRow) {
+ CopyInputRow(aInputRow);
+ return DoAdvanceRow();
+}
+
+uint8_t* SurfaceSink::DoAdvanceRow() {
+ if (mRow >= uint32_t(InputSize().height)) {
+ return nullptr;
+ }
+
+ // If we're vertically flipping the output, we need to flip the invalid rect.
+ // Since we're dealing with an axis-aligned rect, only the y coordinate needs
+ // to change.
+ int32_t invalidY = mFlipVertically ? InputSize().height - (mRow + 1) : mRow;
+ mInvalidRect.UnionRect(mInvalidRect,
+ OrientedIntRect(0, invalidY, InputSize().width, 1));
+
+ mRow = min(uint32_t(InputSize().height), mRow + 1);
+
+ return mRow < uint32_t(InputSize().height) ? GetRowPointer() : nullptr;
+}
+
+nsresult SurfaceSink::Configure(const SurfaceConfig& aConfig) {
+ IntSize surfaceSize = aConfig.mOutputSize;
+
+ // Allocate the frame.
+ // XXX(seth): Once every Decoder subclass uses SurfacePipe, we probably want
+ // to allocate the frame directly here and get rid of Decoder::AllocateFrame
+ // altogether.
+ nsresult rv = aConfig.mDecoder->AllocateFrame(surfaceSize, aConfig.mFormat,
+ aConfig.mAnimParams);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ mImageData = aConfig.mDecoder->mImageData;
+ mImageDataLength = aConfig.mDecoder->mImageDataLength;
+ mFlipVertically = aConfig.mFlipVertically;
+
+ MOZ_ASSERT(mImageData);
+ MOZ_ASSERT(uint64_t(mImageDataLength) == uint64_t(surfaceSize.width) *
+ uint64_t(surfaceSize.height) *
+ sizeof(uint32_t));
+
+ ConfigureFilter(surfaceSize, sizeof(uint32_t));
+ return NS_OK;
+}
+
+uint8_t* SurfaceSink::GetRowPointer() const {
+ // If we're flipping vertically, reverse the order in which we traverse the
+ // rows.
+ uint32_t row = mFlipVertically ? InputSize().height - (mRow + 1) : mRow;
+
+ uint8_t* rowPtr = mImageData + row * InputSize().width * sizeof(uint32_t);
+
+ MOZ_ASSERT(rowPtr >= mImageData);
+ MOZ_ASSERT(rowPtr < mImageData + mImageDataLength);
+ MOZ_ASSERT(rowPtr + InputSize().width * sizeof(uint32_t) <=
+ mImageData + mImageDataLength);
+
+ return rowPtr;
+}
+
+uint8_t* ReorientSurfaceSink::DoAdvanceRowFromBuffer(const uint8_t* aInputRow) {
+ if (mRow >= uint32_t(InputSize().height)) {
+ return nullptr;
+ }
+
+ IntRect dirty = mReorientFn(aInputRow, mRow, mImageData, mSurfaceSize,
+ mSurfaceSize.width * sizeof(uint32_t));
+ auto orientedDirty = OrientedIntRect::FromUnknownRect(dirty);
+ mInvalidRect.UnionRect(mInvalidRect, orientedDirty);
+
+ mRow = min(uint32_t(InputSize().height), mRow + 1);
+
+ return mRow < uint32_t(InputSize().height) ? GetRowPointer() : nullptr;
+}
+
+uint8_t* ReorientSurfaceSink::DoAdvanceRow() {
+ return DoAdvanceRowFromBuffer(mBuffer.get());
+}
+
+nsresult ReorientSurfaceSink::Configure(const ReorientSurfaceConfig& aConfig) {
+ mSurfaceSize = aConfig.mOutputSize.ToUnknownSize();
+
+ // Allocate the frame.
+ // XXX(seth): Once every Decoder subclass uses SurfacePipe, we probably want
+ // to allocate the frame directly here and get rid of Decoder::AllocateFrame
+ // altogether.
+ nsresult rv =
+ aConfig.mDecoder->AllocateFrame(mSurfaceSize, aConfig.mFormat, Nothing());
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ // The filters above us need the unoriented size as the input.
+ auto inputSize =
+ aConfig.mOrientation.ToUnoriented(aConfig.mOutputSize).ToUnknownSize();
+ mBuffer.reset(new (fallible) uint8_t[inputSize.width * sizeof(uint32_t)]);
+ if (MOZ_UNLIKELY(!mBuffer)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ memset(mBuffer.get(), 0xFF, inputSize.width * sizeof(uint32_t));
+
+ mReorientFn = ReorientRow(aConfig.mOrientation);
+ MOZ_ASSERT(mReorientFn);
+
+ mImageData = aConfig.mDecoder->mImageData;
+ mImageDataLength = aConfig.mDecoder->mImageDataLength;
+
+ MOZ_ASSERT(mImageData);
+ MOZ_ASSERT(uint64_t(mImageDataLength) == uint64_t(mSurfaceSize.width) *
+ uint64_t(mSurfaceSize.height) *
+ sizeof(uint32_t));
+
+ ConfigureFilter(inputSize, sizeof(uint32_t));
+ return NS_OK;
+}
+
+uint8_t* ReorientSurfaceSink::GetRowPointer() const { return mBuffer.get(); }
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/SurfacePipe.h b/image/SurfacePipe.h
new file mode 100644
index 0000000000..7dd20276e5
--- /dev/null
+++ b/image/SurfacePipe.h
@@ -0,0 +1,848 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * A SurfacePipe is a pipeline that consists of a series of SurfaceFilters
+ * terminating in a SurfaceSink. Each SurfaceFilter transforms the image data in
+ * some way before the SurfaceSink ultimately writes it to the surface. This
+ * design allows for each transformation to be tested independently, for the
+ * transformations to be combined as needed to meet the needs of different
+ * situations, and for all image decoders to share the same code for these
+ * transformations.
+ *
+ * Writing to the SurfacePipe is done using lambdas that act as generator
+ * functions. Because the SurfacePipe machinery controls where the writes take
+ * place, a bug in an image decoder cannot cause a buffer overflow of the
+ * underlying surface.
+ */
+
+#ifndef mozilla_image_SurfacePipe_h
+#define mozilla_image_SurfacePipe_h
+
+#include <stdint.h>
+
+#include <utility>
+
+#include "AnimationParams.h"
+#include "mozilla/Likely.h"
+#include "mozilla/Maybe.h"
+
+#include "mozilla/UniquePtr.h"
+#include "mozilla/Unused.h"
+#include "mozilla/Variant.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Swizzle.h"
+#include "nsDebug.h"
+#include "Orientation.h"
+
+namespace mozilla {
+namespace image {
+
+class Decoder;
+
+/**
+ * An invalid rect for a surface. Results are given both in the space of the
+ * input image (i.e., before any SurfaceFilters are applied) and in the space
+ * of the output surface (after all SurfaceFilters).
+ */
+struct SurfaceInvalidRect {
+ OrientedIntRect
+ mInputSpaceRect; /// The invalid rect in pre-SurfacePipe space.
+ OrientedIntRect
+ mOutputSpaceRect; /// The invalid rect in post-SurfacePipe space.
+};
+
+/**
+ * An enum used to allow the lambdas passed to WritePixels() to communicate
+ * their state to the caller.
+ */
+enum class WriteState : uint8_t {
+ NEED_MORE_DATA, /// The lambda ran out of data.
+
+ FINISHED, /// The lambda is done writing to the surface; future writes
+ /// will fail.
+
+ FAILURE /// The lambda encountered an error. The caller may recover
+ /// if possible and continue to write. (This never indicates
+ /// an error in the SurfacePipe machinery itself; it's only
+ /// generated by the lambdas.)
+};
+
+/**
+ * A template alias used to make the return value of WritePixels() lambdas
+ * (which may return either a pixel value or a WriteState) easier to specify.
+ */
+template <typename PixelType>
+using NextPixel = Variant<PixelType, WriteState>;
+
+/**
+ * SurfaceFilter is the abstract superclass of SurfacePipe pipeline stages. It
+ * implements the the code that actually writes to the surface - WritePixels()
+ * and the other Write*() methods - which are non-virtual for efficiency.
+ *
+ * SurfaceFilter's API is nonpublic; only SurfacePipe and other SurfaceFilters
+ * should use it. Non-SurfacePipe code should use the methods on SurfacePipe.
+ *
+ * To implement a SurfaceFilter, it's necessary to subclass SurfaceFilter and
+ * implement, at a minimum, the pure virtual methods. It's also necessary to
+ * define a Config struct with a Filter typedef member that identifies the
+ * matching SurfaceFilter class, and a Configure() template method. See an
+ * existing SurfaceFilter subclass, such as RemoveFrameRectFilter, for an
+ * example of how the Configure() method must be implemented. It takes a list of
+ * Config structs, passes the tail of the list to the next filter in the chain's
+ * Configure() method, and then uses the head of the list to configure itself. A
+ * SurfaceFilter's Configure() method must also call
+ * SurfaceFilter::ConfigureFilter() to provide the Write*() methods with the
+ * information they need to do their jobs.
+ */
+class SurfaceFilter {
+ public:
+ SurfaceFilter() : mRowPointer(nullptr), mCol(0), mPixelSize(0) {}
+
+ virtual ~SurfaceFilter() {}
+
+ /**
+ * Reset this surface to the first row. It's legal for this filter to throw
+ * away any previously written data at this point, as all rows must be written
+ * to on every pass.
+ *
+ * @return a pointer to the buffer for the first row.
+ */
+ uint8_t* ResetToFirstRow() {
+ mCol = 0;
+ mRowPointer = DoResetToFirstRow();
+ return mRowPointer;
+ }
+
+ /**
+ * Called by WritePixels() to advance this filter to the next row.
+ *
+ * @return a pointer to the buffer for the next row, or nullptr to indicate
+ * that we've finished the entire surface.
+ */
+ uint8_t* AdvanceRow() {
+ mCol = 0;
+ mRowPointer = DoAdvanceRow();
+ return mRowPointer;
+ }
+
+ /**
+ * Called by WriteBuffer() to advance this filter to the next row, if the
+ * supplied row is a full row.
+ *
+ * @return a pointer to the buffer for the next row, or nullptr to indicate
+ * that we've finished the entire surface.
+ */
+ uint8_t* AdvanceRow(const uint8_t* aInputRow) {
+ mCol = 0;
+ mRowPointer = DoAdvanceRowFromBuffer(aInputRow);
+ return mRowPointer;
+ }
+
+ /// @return a pointer to the buffer for the current row.
+ uint8_t* CurrentRowPointer() const { return mRowPointer; }
+
+ /// @return true if we've finished writing to the surface.
+ bool IsSurfaceFinished() const { return mRowPointer == nullptr; }
+
+ /// @return the input size this filter expects.
+ gfx::IntSize InputSize() const { return mInputSize; }
+
+ /**
+ * Write pixels to the surface one at a time by repeatedly calling a lambda
+ * that yields pixels. WritePixels() is completely memory safe.
+ *
+ * Writing continues until every pixel in the surface has been written to
+ * (i.e., IsSurfaceFinished() returns true) or the lambda returns a WriteState
+ * which WritePixels() will return to the caller.
+ *
+ * The template parameter PixelType must be uint8_t (for paletted surfaces) or
+ * uint32_t (for BGRA/BGRX surfaces) and must be in agreement with the pixel
+ * size passed to ConfigureFilter().
+ *
+ * XXX(seth): We'll remove all support for paletted surfaces in bug 1247520,
+ * which means we can remove the PixelType template parameter from this
+ * method.
+ *
+ * @param aFunc A lambda that functions as a generator, yielding the next
+ * pixel in the surface each time it's called. The lambda must
+ * return a NextPixel<PixelType> value.
+ *
+ * @return A WriteState value indicating the lambda generator's state.
+ * WritePixels() itself will return WriteState::FINISHED if writing
+ * has finished, regardless of the lambda's internal state.
+ */
+ template <typename PixelType, typename Func>
+ WriteState WritePixels(Func aFunc) {
+ Maybe<WriteState> result;
+ while (
+ !(result = DoWritePixelsToRow<PixelType>(std::forward<Func>(aFunc)))) {
+ }
+
+ return *result;
+ }
+
+ /**
+ * Write pixels to the surface by calling a lambda which may write as many
+ * pixels as there is remaining to complete the row. It is not completely
+ * memory safe as it trusts the underlying decoder not to overrun the given
+ * buffer, however it is an acceptable tradeoff for performance.
+ *
+ * Writing continues until every pixel in the surface has been written to
+ * (i.e., IsSurfaceFinished() returns true) or the lambda returns a WriteState
+ * which WritePixelBlocks() will return to the caller.
+ *
+ * The template parameter PixelType must be uint8_t (for paletted surfaces) or
+ * uint32_t (for BGRA/BGRX surfaces) and must be in agreement with the pixel
+ * size passed to ConfigureFilter().
+ *
+ * XXX(seth): We'll remove all support for paletted surfaces in bug 1247520,
+ * which means we can remove the PixelType template parameter from this
+ * method.
+ *
+ * @param aFunc A lambda that functions as a generator, yielding at most the
+ * maximum number of pixels requested. The lambda must accept a
+ * pointer argument to the first pixel to write, a maximum
+ * number of pixels to write as part of the block, and return a
+ * NextPixel<PixelType> value.
+ *
+ * @return A WriteState value indicating the lambda generator's state.
+ * WritePixelBlocks() itself will return WriteState::FINISHED if
+ * writing has finished, regardless of the lambda's internal state.
+ */
+ template <typename PixelType, typename Func>
+ WriteState WritePixelBlocks(Func aFunc) {
+ Maybe<WriteState> result;
+ while (!(result = DoWritePixelBlockToRow<PixelType>(
+ std::forward<Func>(aFunc)))) {
+ }
+
+ return *result;
+ }
+
+ /**
+ * A variant of WritePixels() that writes a single row of pixels to the
+ * surface one at a time by repeatedly calling a lambda that yields pixels.
+ * WritePixelsToRow() is completely memory safe.
+ *
+ * Writing continues until every pixel in the row has been written to. If the
+ * surface is complete at that pointer, WriteState::FINISHED is returned;
+ * otherwise, WritePixelsToRow() returns WriteState::NEED_MORE_DATA. The
+ * lambda can terminate writing early by returning a WriteState itself, which
+ * WritePixelsToRow() will return to the caller.
+ *
+ * The template parameter PixelType must be uint8_t (for paletted surfaces) or
+ * uint32_t (for BGRA/BGRX surfaces) and must be in agreement with the pixel
+ * size passed to ConfigureFilter().
+ *
+ * XXX(seth): We'll remove all support for paletted surfaces in bug 1247520,
+ * which means we can remove the PixelType template parameter from this
+ * method.
+ *
+ * @param aFunc A lambda that functions as a generator, yielding the next
+ * pixel in the surface each time it's called. The lambda must
+ * return a NextPixel<PixelType> value.
+ *
+ * @return A WriteState value indicating the lambda generator's state.
+ * WritePixels() itself will return WriteState::FINISHED if writing
+ * the entire surface has finished, or WriteState::NEED_MORE_DATA if
+ * writing the row has finished, regardless of the lambda's internal
+ * state.
+ */
+ template <typename PixelType, typename Func>
+ WriteState WritePixelsToRow(Func aFunc) {
+ return DoWritePixelsToRow<PixelType>(std::forward<Func>(aFunc))
+ .valueOr(WriteState::NEED_MORE_DATA);
+ }
+
+ /**
+ * Write a row to the surface by copying from a buffer. This is bounds checked
+ * and memory safe with respect to the surface, but care must still be taken
+ * by the caller not to overread the source buffer. This variant of
+ * WriteBuffer() requires a source buffer which contains |mInputSize.width|
+ * pixels.
+ *
+ * The template parameter PixelType must be uint8_t (for paletted surfaces) or
+ * uint32_t (for BGRA/BGRX surfaces) and must be in agreement with the pixel
+ * size passed to ConfigureFilter().
+ *
+ * XXX(seth): We'll remove all support for paletted surfaces in bug 1247520,
+ * which means we can remove the PixelType template parameter from this
+ * method.
+ *
+ * @param aSource A buffer to copy from. This buffer must be
+ * |mInputSize.width| pixels wide, which means
+ * |mInputSize.width * sizeof(PixelType)| bytes. May not be
+ * null.
+ *
+ * @return WriteState::FINISHED if the entire surface has been written to.
+ * Otherwise, returns WriteState::NEED_MORE_DATA. If a null |aSource|
+ * value is passed, returns WriteState::FAILURE.
+ */
+ template <typename PixelType>
+ WriteState WriteBuffer(const PixelType* aSource) {
+ MOZ_ASSERT(mPixelSize == 1 || mPixelSize == 4);
+ MOZ_ASSERT_IF(mPixelSize == 1, sizeof(PixelType) == sizeof(uint8_t));
+ MOZ_ASSERT_IF(mPixelSize == 4, sizeof(PixelType) == sizeof(uint32_t));
+
+ if (IsSurfaceFinished()) {
+ return WriteState::FINISHED; // Already done.
+ }
+
+ if (MOZ_UNLIKELY(!aSource)) {
+ NS_WARNING("Passed a null pointer to WriteBuffer");
+ return WriteState::FAILURE;
+ }
+
+ AdvanceRow(reinterpret_cast<const uint8_t*>(aSource));
+ return IsSurfaceFinished() ? WriteState::FINISHED
+ : WriteState::NEED_MORE_DATA;
+ }
+
+ /**
+ * Write a row to the surface by copying from a buffer. This is bounds checked
+ * and memory safe with respect to the surface, but care must still be taken
+ * by the caller not to overread the source buffer. This variant of
+ * WriteBuffer() reads at most @aLength pixels from the buffer and writes them
+ * to the row starting at @aStartColumn. Any pixels in columns before
+ * @aStartColumn or after the pixels copied from the buffer are cleared.
+ *
+ * Bounds checking failures produce warnings in debug builds because although
+ * the bounds checking maintains safety, this kind of failure could indicate a
+ * bug in the calling code.
+ *
+ * The template parameter PixelType must be uint8_t (for paletted surfaces) or
+ * uint32_t (for BGRA/BGRX surfaces) and must be in agreement with the pixel
+ * size passed to ConfigureFilter().
+ *
+ * XXX(seth): We'll remove all support for paletted surfaces in bug 1247520,
+ * which means we can remove the PixelType template parameter from this
+ * method.
+ *
+ * @param aSource A buffer to copy from. This buffer must be @aLength pixels
+ * wide, which means |aLength * sizeof(PixelType)| bytes. May
+ * not be null.
+ * @param aStartColumn The column to start writing to in the row. Columns
+ * before this are cleared.
+ * @param aLength The number of bytes, at most, which may be copied from
+ * @aSource. Fewer bytes may be copied in practice due to
+ * bounds checking.
+ *
+ * @return WriteState::FINISHED if the entire surface has been written to.
+ * Otherwise, returns WriteState::NEED_MORE_DATA. If a null |aSource|
+ * value is passed, returns WriteState::FAILURE.
+ */
+ template <typename PixelType>
+ WriteState WriteBuffer(const PixelType* aSource, const size_t aStartColumn,
+ const size_t aLength) {
+ MOZ_ASSERT(mPixelSize == 1 || mPixelSize == 4);
+ MOZ_ASSERT_IF(mPixelSize == 1, sizeof(PixelType) == sizeof(uint8_t));
+ MOZ_ASSERT_IF(mPixelSize == 4, sizeof(PixelType) == sizeof(uint32_t));
+
+ if (IsSurfaceFinished()) {
+ return WriteState::FINISHED; // Already done.
+ }
+
+ if (MOZ_UNLIKELY(!aSource)) {
+ NS_WARNING("Passed a null pointer to WriteBuffer");
+ return WriteState::FAILURE;
+ }
+
+ PixelType* dest = reinterpret_cast<PixelType*>(mRowPointer);
+
+ // Clear the area before |aStartColumn|.
+ const size_t prefixLength =
+ std::min<size_t>(mInputSize.width, aStartColumn);
+ if (MOZ_UNLIKELY(prefixLength != aStartColumn)) {
+ NS_WARNING("Provided starting column is out-of-bounds in WriteBuffer");
+ }
+
+ memset(dest, 0, mInputSize.width * sizeof(PixelType));
+ dest += prefixLength;
+
+ // Write |aLength| pixels from |aSource| into the row, with bounds checking.
+ const size_t bufferLength =
+ std::min<size_t>(mInputSize.width - prefixLength, aLength);
+ if (MOZ_UNLIKELY(bufferLength != aLength)) {
+ NS_WARNING("Provided buffer length is out-of-bounds in WriteBuffer");
+ }
+
+ memcpy(dest, aSource, bufferLength * sizeof(PixelType));
+ dest += bufferLength;
+
+ // Clear the rest of the row.
+ const size_t suffixLength =
+ mInputSize.width - (prefixLength + bufferLength);
+ memset(dest, 0, suffixLength * sizeof(PixelType));
+
+ AdvanceRow();
+
+ return IsSurfaceFinished() ? WriteState::FINISHED
+ : WriteState::NEED_MORE_DATA;
+ }
+
+ /**
+ * Write an empty row to the surface. If some pixels have already been written
+ * to this row, they'll be discarded.
+ *
+ * @return WriteState::FINISHED if the entire surface has been written to.
+ * Otherwise, returns WriteState::NEED_MORE_DATA.
+ */
+ WriteState WriteEmptyRow() {
+ if (IsSurfaceFinished()) {
+ return WriteState::FINISHED; // Already done.
+ }
+
+ memset(mRowPointer, 0, mInputSize.width * mPixelSize);
+ AdvanceRow();
+
+ return IsSurfaceFinished() ? WriteState::FINISHED
+ : WriteState::NEED_MORE_DATA;
+ }
+
+ /**
+ * Write a row to the surface by calling a lambda that uses a pointer to
+ * directly write to the row. This is unsafe because SurfaceFilter can't
+ * provide any bounds checking; that's up to the lambda itself. For this
+ * reason, the other Write*() methods should be preferred whenever it's
+ * possible to use them; WriteUnsafeComputedRow() should be used only when
+ * it's absolutely necessary to avoid extra copies or other performance
+ * penalties.
+ *
+ * This method should never be exposed to SurfacePipe consumers; it's strictly
+ * for use in SurfaceFilters. If external code needs this method, it should
+ * probably be turned into a SurfaceFilter.
+ *
+ * The template parameter PixelType must be uint8_t (for paletted surfaces) or
+ * uint32_t (for BGRA/BGRX surfaces) and must be in agreement with the pixel
+ * size passed to ConfigureFilter().
+ *
+ * XXX(seth): We'll remove all support for paletted surfaces in bug 1247520,
+ * which means we can remove the PixelType template parameter from this
+ * method.
+ *
+ * @param aFunc A lambda that writes directly to the row.
+ *
+ * @return WriteState::FINISHED if the entire surface has been written to.
+ * Otherwise, returns WriteState::NEED_MORE_DATA.
+ */
+ template <typename PixelType, typename Func>
+ WriteState WriteUnsafeComputedRow(Func aFunc) {
+ MOZ_ASSERT(mPixelSize == 1 || mPixelSize == 4);
+ MOZ_ASSERT_IF(mPixelSize == 1, sizeof(PixelType) == sizeof(uint8_t));
+ MOZ_ASSERT_IF(mPixelSize == 4, sizeof(PixelType) == sizeof(uint32_t));
+
+ if (IsSurfaceFinished()) {
+ return WriteState::FINISHED; // Already done.
+ }
+
+ // Call the provided lambda with a pointer to the buffer for the current
+ // row. This is unsafe because we can't do any bounds checking; the lambda
+ // itself has to be responsible for that.
+ PixelType* rowPtr = reinterpret_cast<PixelType*>(mRowPointer);
+ aFunc(rowPtr, mInputSize.width);
+ AdvanceRow();
+
+ return IsSurfaceFinished() ? WriteState::FINISHED
+ : WriteState::NEED_MORE_DATA;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Methods Subclasses Should Override
+ //////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * @return a SurfaceInvalidRect representing the region of the surface that
+ * has been written to since the last time TakeInvalidRect() was
+ * called, or Nothing() if the region is empty (i.e. nothing has been
+ * written).
+ */
+ virtual Maybe<SurfaceInvalidRect> TakeInvalidRect() = 0;
+
+ protected:
+ /**
+ * Called by ResetToFirstRow() to actually perform the reset. It's legal to
+ * throw away any previously written data at this point, as all rows must be
+ * written to on every pass.
+ */
+ virtual uint8_t* DoResetToFirstRow() = 0;
+
+ /**
+ * Called by AdvanceRow() to actually advance this filter to the next row.
+ *
+ * @param aInputRow The input row supplied by the decoder.
+ *
+ * @return a pointer to the buffer for the next row, or nullptr to indicate
+ * that we've finished the entire surface.
+ */
+ virtual uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) = 0;
+
+ /**
+ * Called by AdvanceRow() to actually advance this filter to the next row.
+ *
+ * @return a pointer to the buffer for the next row, or nullptr to indicate
+ * that we've finished the entire surface.
+ */
+ virtual uint8_t* DoAdvanceRow() = 0;
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Methods For Internal Use By Subclasses
+ //////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Called by subclasses' Configure() methods to initialize the configuration
+ * of this filter. After the filter is configured, calls ResetToFirstRow().
+ *
+ * @param aInputSize The input size of this filter, in pixels. The previous
+ * filter in the chain will expect to write into rows
+ * |aInputSize.width| pixels wide.
+ * @param aPixelSize How large, in bytes, each pixel in the surface is. This
+ * should be either 1 for paletted images or 4 for BGRA/BGRX
+ * images.
+ */
+ void ConfigureFilter(gfx::IntSize aInputSize, uint8_t aPixelSize) {
+ mInputSize = aInputSize;
+ mPixelSize = aPixelSize;
+
+ ResetToFirstRow();
+ }
+
+ /**
+ * Called by subclasses' DoAdvanceRowFromBuffer() methods to copy a decoder
+ * supplied row buffer into its internal row pointer. Ideally filters at the
+ * top of the filter pipeline are able to consume the decoder row buffer
+ * directly without the extra copy prior to performing its transformation.
+ *
+ * @param aInputRow The input row supplied by the decoder.
+ */
+ void CopyInputRow(const uint8_t* aInputRow) {
+ MOZ_ASSERT(aInputRow);
+ MOZ_ASSERT(mCol == 0);
+ memcpy(mRowPointer, aInputRow, mPixelSize * mInputSize.width);
+ }
+
+ private:
+ /**
+ * An internal method used to implement WritePixelBlocks. This method writes
+ * up to the number of pixels necessary to complete the row and returns Some()
+ * if we either finished the entire surface or the lambda returned a
+ * WriteState indicating that we should return to the caller. If the row was
+ * successfully written without either of those things happening, it returns
+ * Nothing(), allowing WritePixelBlocks() to iterate to fill as many rows as
+ * possible.
+ */
+ template <typename PixelType, typename Func>
+ Maybe<WriteState> DoWritePixelBlockToRow(Func aFunc) {
+ MOZ_ASSERT(mPixelSize == 1 || mPixelSize == 4);
+ MOZ_ASSERT_IF(mPixelSize == 1, sizeof(PixelType) == sizeof(uint8_t));
+ MOZ_ASSERT_IF(mPixelSize == 4, sizeof(PixelType) == sizeof(uint32_t));
+
+ if (IsSurfaceFinished()) {
+ return Some(WriteState::FINISHED); // We're already done.
+ }
+
+ PixelType* rowPtr = reinterpret_cast<PixelType*>(mRowPointer);
+ int32_t remainder = mInputSize.width - mCol;
+ auto [written, result] = aFunc(&rowPtr[mCol], remainder);
+ if (written == remainder) {
+ MOZ_ASSERT(result.isNothing());
+ mCol = mInputSize.width;
+ AdvanceRow(); // We've finished the row.
+ return IsSurfaceFinished() ? Some(WriteState::FINISHED) : Nothing();
+ }
+
+ MOZ_ASSERT(written >= 0 && written < remainder);
+ MOZ_ASSERT(result.isSome());
+
+ mCol += written;
+ if (*result == WriteState::FINISHED) {
+ ZeroOutRestOfSurface<PixelType>();
+ }
+
+ return result;
+ }
+
+ /**
+ * An internal method used to implement both WritePixels() and
+ * WritePixelsToRow(). Those methods differ only in their behavior after a row
+ * is successfully written - WritePixels() continues to write another row,
+ * while WritePixelsToRow() returns to the caller. This method writes a single
+ * row and returns Some() if we either finished the entire surface or the
+ * lambda returned a WriteState indicating that we should return to the
+ * caller. If the row was successfully written without either of those things
+ * happening, it returns Nothing(), allowing WritePixels() and
+ * WritePixelsToRow() to implement their respective behaviors.
+ */
+ template <typename PixelType, typename Func>
+ Maybe<WriteState> DoWritePixelsToRow(Func aFunc) {
+ MOZ_ASSERT(mPixelSize == 1 || mPixelSize == 4);
+ MOZ_ASSERT_IF(mPixelSize == 1, sizeof(PixelType) == sizeof(uint8_t));
+ MOZ_ASSERT_IF(mPixelSize == 4, sizeof(PixelType) == sizeof(uint32_t));
+
+ if (IsSurfaceFinished()) {
+ return Some(WriteState::FINISHED); // We're already done.
+ }
+
+ PixelType* rowPtr = reinterpret_cast<PixelType*>(mRowPointer);
+
+ for (; mCol < mInputSize.width; ++mCol) {
+ NextPixel<PixelType> result = aFunc();
+ if (result.template is<PixelType>()) {
+ rowPtr[mCol] = result.template as<PixelType>();
+ continue;
+ }
+
+ switch (result.template as<WriteState>()) {
+ case WriteState::NEED_MORE_DATA:
+ return Some(WriteState::NEED_MORE_DATA);
+
+ case WriteState::FINISHED:
+ ZeroOutRestOfSurface<PixelType>();
+ return Some(WriteState::FINISHED);
+
+ case WriteState::FAILURE:
+ // Note that we don't need to record this anywhere, because this
+ // indicates an error in aFunc, and there's nothing wrong with our
+ // machinery. The caller can recover as needed and continue writing to
+ // the row.
+ return Some(WriteState::FAILURE);
+ }
+ }
+
+ AdvanceRow(); // We've finished the row.
+
+ return IsSurfaceFinished() ? Some(WriteState::FINISHED) : Nothing();
+ }
+
+ template <typename PixelType>
+ void ZeroOutRestOfSurface() {
+ WritePixels<PixelType>([] { return AsVariant(PixelType(0)); });
+ }
+
+ gfx::IntSize mInputSize; /// The size of the input this filter expects.
+ uint8_t* mRowPointer; /// Pointer to the current row or null if finished.
+ int32_t mCol; /// The current column we're writing to. (0-indexed)
+ uint8_t mPixelSize; /// How large each pixel in the surface is, in bytes.
+};
+
+/**
+ * SurfacePipe is the public API that decoders should use to interact with a
+ * SurfaceFilter pipeline.
+ */
+class SurfacePipe {
+ public:
+ SurfacePipe() {}
+
+ SurfacePipe(SurfacePipe&& aOther) : mHead(std::move(aOther.mHead)) {}
+
+ ~SurfacePipe() {}
+
+ SurfacePipe& operator=(SurfacePipe&& aOther) {
+ MOZ_ASSERT(this != &aOther);
+ mHead = std::move(aOther.mHead);
+ return *this;
+ }
+
+ /// Begins a new pass, seeking to the first row of the surface.
+ void ResetToFirstRow() {
+ MOZ_ASSERT(mHead, "Use before configured!");
+ mHead->ResetToFirstRow();
+ }
+
+ /**
+ * Write pixels to the surface one at a time by repeatedly calling a lambda
+ * that yields pixels. WritePixels() is completely memory safe.
+ *
+ * @see SurfaceFilter::WritePixels() for the canonical documentation.
+ */
+ template <typename PixelType, typename Func>
+ WriteState WritePixels(Func aFunc) {
+ MOZ_ASSERT(mHead, "Use before configured!");
+ return mHead->WritePixels<PixelType>(std::forward<Func>(aFunc));
+ }
+
+ /**
+ * A variant of WritePixels() that writes up to a single row of pixels to the
+ * surface in blocks by repeatedly calling a lambda that yields up to the
+ * requested number of pixels.
+ *
+ * @see SurfaceFilter::WritePixelBlocks() for the canonical documentation.
+ */
+ template <typename PixelType, typename Func>
+ WriteState WritePixelBlocks(Func aFunc) {
+ MOZ_ASSERT(mHead, "Use before configured!");
+ return mHead->WritePixelBlocks<PixelType>(std::forward<Func>(aFunc));
+ }
+
+ /**
+ * A variant of WritePixels() that writes a single row of pixels to the
+ * surface one at a time by repeatedly calling a lambda that yields pixels.
+ * WritePixelsToRow() is completely memory safe.
+ *
+ * @see SurfaceFilter::WritePixelsToRow() for the canonical documentation.
+ */
+ template <typename PixelType, typename Func>
+ WriteState WritePixelsToRow(Func aFunc) {
+ MOZ_ASSERT(mHead, "Use before configured!");
+ return mHead->WritePixelsToRow<PixelType>(std::forward<Func>(aFunc));
+ }
+
+ /**
+ * Write a row to the surface by copying from a buffer. This is bounds checked
+ * and memory safe with respect to the surface, but care must still be taken
+ * by the caller not to overread the source buffer. This variant of
+ * WriteBuffer() requires a source buffer which contains |mInputSize.width|
+ * pixels.
+ *
+ * @see SurfaceFilter::WriteBuffer() for the canonical documentation.
+ */
+ template <typename PixelType>
+ WriteState WriteBuffer(const PixelType* aSource) {
+ MOZ_ASSERT(mHead, "Use before configured!");
+ return mHead->WriteBuffer<PixelType>(aSource);
+ }
+
+ /**
+ * Write a row to the surface by copying from a buffer. This is bounds checked
+ * and memory safe with respect to the surface, but care must still be taken
+ * by the caller not to overread the source buffer. This variant of
+ * WriteBuffer() reads at most @aLength pixels from the buffer and writes them
+ * to the row starting at @aStartColumn. Any pixels in columns before
+ * @aStartColumn or after the pixels copied from the buffer are cleared.
+ *
+ * @see SurfaceFilter::WriteBuffer() for the canonical documentation.
+ */
+ template <typename PixelType>
+ WriteState WriteBuffer(const PixelType* aSource, const size_t aStartColumn,
+ const size_t aLength) {
+ MOZ_ASSERT(mHead, "Use before configured!");
+ return mHead->WriteBuffer<PixelType>(aSource, aStartColumn, aLength);
+ }
+
+ /**
+ * Write an empty row to the surface. If some pixels have already been written
+ * to this row, they'll be discarded.
+ *
+ * @see SurfaceFilter::WriteEmptyRow() for the canonical documentation.
+ */
+ WriteState WriteEmptyRow() {
+ MOZ_ASSERT(mHead, "Use before configured!");
+ return mHead->WriteEmptyRow();
+ }
+
+ /// @return true if we've finished writing to the surface.
+ bool IsSurfaceFinished() const { return mHead->IsSurfaceFinished(); }
+
+ /// @see SurfaceFilter::TakeInvalidRect() for the canonical documentation.
+ Maybe<SurfaceInvalidRect> TakeInvalidRect() const {
+ MOZ_ASSERT(mHead, "Use before configured!");
+ return mHead->TakeInvalidRect();
+ }
+
+ private:
+ friend class SurfacePipeFactory;
+ friend class TestSurfacePipeFactory;
+
+ explicit SurfacePipe(UniquePtr<SurfaceFilter>&& aHead)
+ : mHead(std::move(aHead)) {}
+
+ SurfacePipe(const SurfacePipe&) = delete;
+ SurfacePipe& operator=(const SurfacePipe&) = delete;
+
+ UniquePtr<SurfaceFilter> mHead; /// The first filter in the chain.
+};
+
+/**
+ * AbstractSurfaceSink contains shared implementation for both SurfaceSink and
+ * ReorientSurfaceSink.
+ */
+class AbstractSurfaceSink : public SurfaceFilter {
+ public:
+ AbstractSurfaceSink()
+ : mImageData(nullptr),
+ mImageDataLength(0),
+ mRow(0),
+ mFlipVertically(false) {}
+
+ Maybe<SurfaceInvalidRect> TakeInvalidRect() final;
+
+ protected:
+ uint8_t* DoResetToFirstRow() final;
+ virtual uint8_t* GetRowPointer() const = 0;
+
+ OrientedIntRect
+ mInvalidRect; /// The region of the surface that has been written
+ /// to since the last call to TakeInvalidRect().
+ uint8_t* mImageData; /// A pointer to the beginning of the surface data.
+ uint32_t mImageDataLength; /// The length of the surface data.
+ uint32_t mRow; /// The row to which we're writing. (0-indexed)
+ bool mFlipVertically; /// If true, write the rows from top to bottom.
+};
+
+class SurfaceSink;
+
+/// A configuration struct for SurfaceSink.
+struct SurfaceConfig {
+ using Filter = SurfaceSink;
+ Decoder* mDecoder; /// Which Decoder to use to allocate the surface.
+ gfx::IntSize mOutputSize; /// The size of the surface.
+ gfx::SurfaceFormat mFormat; /// The surface format (BGRA or BGRX).
+ bool mFlipVertically; /// If true, write the rows from bottom to top.
+ Maybe<AnimationParams> mAnimParams; /// Given for animated images.
+};
+
+/**
+ * A sink for surfaces. It handles the allocation of the surface and protects
+ * against buffer overflow. This sink should be used for most images.
+ *
+ * Sinks must always be at the end of the SurfaceFilter chain.
+ */
+class SurfaceSink final : public AbstractSurfaceSink {
+ public:
+ nsresult Configure(const SurfaceConfig& aConfig);
+
+ protected:
+ uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) final;
+ uint8_t* DoAdvanceRow() final;
+ uint8_t* GetRowPointer() const final;
+};
+
+class ReorientSurfaceSink;
+
+/// A configuration struct for ReorientSurfaceSink.
+struct ReorientSurfaceConfig {
+ using Filter = ReorientSurfaceSink;
+ Decoder* mDecoder; /// Which Decoder to use to allocate the surface.
+ OrientedIntSize mOutputSize; /// The size of the surface.
+ gfx::SurfaceFormat mFormat; /// The surface format (BGRA or BGRX).
+ Orientation mOrientation; /// The desired orientation of the surface data.
+};
+
+/**
+ * A sink for surfaces. It handles the allocation of the surface and protects
+ * against buffer overflow. This sink should be used for images which have a
+ * non-identity orientation which we want to apply during decoding.
+ *
+ * Sinks must always be at the end of the SurfaceFilter chain.
+ */
+class ReorientSurfaceSink final : public AbstractSurfaceSink {
+ public:
+ nsresult Configure(const ReorientSurfaceConfig& aConfig);
+
+ protected:
+ uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) final;
+ uint8_t* DoAdvanceRow() final;
+ uint8_t* GetRowPointer() const final;
+
+ UniquePtr<uint8_t[]> mBuffer;
+ gfx::ReorientRowFn mReorientFn;
+ gfx::IntSize mSurfaceSize;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_SurfacePipe_h
diff --git a/image/SurfacePipeFactory.h b/image/SurfacePipeFactory.h
new file mode 100644
index 0000000000..004ce349a6
--- /dev/null
+++ b/image/SurfacePipeFactory.h
@@ -0,0 +1,679 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_SurfacePipeFactory_h
+#define mozilla_image_SurfacePipeFactory_h
+
+#include "SurfacePipe.h"
+#include "SurfaceFilters.h"
+
+namespace mozilla {
+namespace image {
+
+namespace detail {
+
+/**
+ * FilterPipeline is a helper template for SurfacePipeFactory that determines
+ * the full type of the sequence of SurfaceFilters that a sequence of
+ * configuration structs corresponds to. To make this work, all configuration
+ * structs must include a typedef 'Filter' that identifies the SurfaceFilter
+ * they configure.
+ */
+template <typename... Configs>
+struct FilterPipeline;
+
+template <typename Config, typename... Configs>
+struct FilterPipeline<Config, Configs...> {
+ typedef typename Config::template Filter<
+ typename FilterPipeline<Configs...>::Type>
+ Type;
+};
+
+template <typename Config>
+struct FilterPipeline<Config> {
+ typedef typename Config::Filter Type;
+};
+
+} // namespace detail
+
+/**
+ * Flags for SurfacePipeFactory, used in conjunction with the factory functions
+ * in SurfacePipeFactory to enable or disable various SurfacePipe
+ * functionality.
+ */
+enum class SurfacePipeFlags {
+ DEINTERLACE = 1 << 0, // If set, deinterlace the image.
+
+ ADAM7_INTERPOLATE =
+ 1 << 1, // If set, the caller is deinterlacing the
+ // image using ADAM7, and we may want to
+ // interpolate it for better intermediate results.
+
+ FLIP_VERTICALLY = 1 << 2, // If set, flip the image vertically.
+
+ PROGRESSIVE_DISPLAY = 1 << 3, // If set, we expect the image to be displayed
+ // progressively. This enables features that
+ // result in a better user experience for
+ // progressive display but which may be more
+ // computationally expensive.
+
+ PREMULTIPLY_ALPHA = 1 << 4, // If set, we want to premultiply the alpha
+ // channel and the individual color channels.
+};
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SurfacePipeFlags)
+
+class SurfacePipeFactory {
+ public:
+ /**
+ * Creates and initializes a normal (i.e., non-paletted) SurfacePipe.
+ *
+ * @param aDecoder The decoder whose current frame the SurfacePipe will write
+ * to.
+ * @param aInputSize The original size of the image.
+ * @param aOutputSize The size the SurfacePipe should output. Must be the same
+ * as @aInputSize or smaller. If smaller, the image will be
+ * downscaled during decoding.
+ * @param aFrameRect The portion of the image that actually contains data.
+ * @param aFormat The surface format of the image; generally B8G8R8A8 or
+ * B8G8R8X8.
+ * @param aAnimParams Extra parameters used by animated images.
+ * @param aFlags Flags enabling or disabling various functionality for the
+ * SurfacePipe; see the SurfacePipeFlags documentation for more
+ * information.
+ *
+ * @return A SurfacePipe if the parameters allowed one to be created
+ * successfully, or Nothing() if the SurfacePipe could not be
+ * initialized.
+ */
+ static Maybe<SurfacePipe> CreateSurfacePipe(
+ Decoder* aDecoder, const OrientedIntSize& aInputSize,
+ const OrientedIntSize& aOutputSize, const OrientedIntRect& aFrameRect,
+ gfx::SurfaceFormat aInFormat, gfx::SurfaceFormat aOutFormat,
+ const Maybe<AnimationParams>& aAnimParams, qcms_transform* aTransform,
+ SurfacePipeFlags aFlags) {
+ const bool deinterlace = bool(aFlags & SurfacePipeFlags::DEINTERLACE);
+ const bool flipVertically =
+ bool(aFlags & SurfacePipeFlags::FLIP_VERTICALLY);
+ const bool progressiveDisplay =
+ bool(aFlags & SurfacePipeFlags::PROGRESSIVE_DISPLAY);
+ const bool downscale = aInputSize != aOutputSize;
+ const bool removeFrameRect = !aFrameRect.IsEqualEdges(
+ OrientedIntRect(OrientedIntPoint(0, 0), aInputSize));
+ const bool blendAnimation = aAnimParams.isSome();
+ const bool colorManagement = aTransform != nullptr;
+ const bool premultiplyAlpha =
+ bool(aFlags & SurfacePipeFlags::PREMULTIPLY_ALPHA);
+
+ MOZ_ASSERT(aInFormat == gfx::SurfaceFormat::R8G8B8 ||
+ aInFormat == gfx::SurfaceFormat::R8G8B8A8 ||
+ aInFormat == gfx::SurfaceFormat::R8G8B8X8 ||
+ aInFormat == gfx::SurfaceFormat::OS_RGBA ||
+ aInFormat == gfx::SurfaceFormat::OS_RGBX);
+
+ MOZ_ASSERT(aOutFormat == gfx::SurfaceFormat::OS_RGBA ||
+ aOutFormat == gfx::SurfaceFormat::OS_RGBX);
+
+ MOZ_ASSERT(aDecoder->GetOrientation().IsIdentity());
+
+ const bool inFormatRgb = aInFormat == gfx::SurfaceFormat::R8G8B8;
+
+ const bool inFormatOpaque = aInFormat == gfx::SurfaceFormat::OS_RGBX ||
+ aInFormat == gfx::SurfaceFormat::R8G8B8X8 ||
+ inFormatRgb;
+ const bool outFormatOpaque = aOutFormat == gfx::SurfaceFormat::OS_RGBX;
+
+ const bool inFormatOrder = aInFormat == gfx::SurfaceFormat::R8G8B8A8 ||
+ aInFormat == gfx::SurfaceFormat::R8G8B8X8;
+ const bool outFormatOrder = aOutFormat == gfx::SurfaceFormat::R8G8B8A8 ||
+ aOutFormat == gfx::SurfaceFormat::R8G8B8X8;
+
+ // Early swizzles are for unpacking RGB or forcing RGBA/BGRA_U32 to
+ // RGBX/BGRX_U32. We should never want to premultiply in either case,
+ // because the image's alpha channel will always be opaque. This must be
+ // done before downscaling and color management.
+ bool unpackOrMaskSwizzle =
+ inFormatRgb ||
+ (!inFormatOpaque && outFormatOpaque && inFormatOrder == outFormatOrder);
+
+ // Late swizzles are for premultiplying RGBA/BGRA_U32 and/or possible
+ // converting between RGBA and BGRA_U32. It must happen after color
+ // management, and before downscaling.
+ bool swapOrAlphaSwizzle =
+ (!inFormatRgb && inFormatOrder != outFormatOrder) || premultiplyAlpha;
+
+ if (unpackOrMaskSwizzle && swapOrAlphaSwizzle) {
+ MOZ_ASSERT_UNREACHABLE("Early and late swizzles not supported");
+ return Nothing();
+ }
+
+ if (!unpackOrMaskSwizzle && !swapOrAlphaSwizzle &&
+ aInFormat != aOutFormat) {
+ MOZ_ASSERT_UNREACHABLE("Need to swizzle, but not configured to");
+ return Nothing();
+ }
+
+ // Don't interpolate if we're sure we won't show this surface to the user
+ // until it's completely decoded. The final pass of an ADAM7 image doesn't
+ // need interpolation, so we only need to interpolate if we'll be displaying
+ // the image while it's still being decoded.
+ const bool adam7Interpolate =
+ bool(aFlags & SurfacePipeFlags::ADAM7_INTERPOLATE) &&
+ progressiveDisplay;
+
+ if (deinterlace && adam7Interpolate) {
+ MOZ_ASSERT_UNREACHABLE("ADAM7 deinterlacing is handled by libpng");
+ return Nothing();
+ }
+
+ // Construct configurations for the SurfaceFilters. Note that the order of
+ // these filters is significant. We want to deinterlace or interpolate raw
+ // input rows, before any other transformations, and we want to remove the
+ // frame rect (which may involve adding blank rows or columns to the image)
+ // before any downscaling, so that the new rows and columns are taken into
+ // account.
+ DeinterlacingConfig<uint32_t> deinterlacingConfig{progressiveDisplay};
+ ADAM7InterpolatingConfig interpolatingConfig;
+ RemoveFrameRectConfig removeFrameRectConfig{aFrameRect.ToUnknownRect()};
+ BlendAnimationConfig blendAnimationConfig{aDecoder};
+ DownscalingConfig downscalingConfig{aInputSize.ToUnknownSize(), aOutFormat};
+ ColorManagementConfig colorManagementConfig{aTransform};
+ SwizzleConfig swizzleConfig{aInFormat, aOutFormat, premultiplyAlpha};
+ SurfaceConfig surfaceConfig{aDecoder, aOutputSize.ToUnknownSize(),
+ aOutFormat, flipVertically, aAnimParams};
+
+ Maybe<SurfacePipe> pipe;
+
+ if (unpackOrMaskSwizzle) {
+ if (colorManagement) {
+ if (downscale) {
+ MOZ_ASSERT(!blendAnimation);
+ if (removeFrameRect) {
+ if (deinterlace) {
+ pipe = MakePipe(swizzleConfig, deinterlacingConfig,
+ removeFrameRectConfig, downscalingConfig,
+ colorManagementConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(swizzleConfig, interpolatingConfig,
+ removeFrameRectConfig, downscalingConfig,
+ colorManagementConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(swizzleConfig, removeFrameRectConfig,
+ downscalingConfig, colorManagementConfig,
+ surfaceConfig);
+ }
+ } else { // (removeFrameRect is false)
+ if (deinterlace) {
+ pipe = MakePipe(swizzleConfig, deinterlacingConfig,
+ downscalingConfig, colorManagementConfig,
+ surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(swizzleConfig, interpolatingConfig,
+ downscalingConfig, colorManagementConfig,
+ surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(swizzleConfig, downscalingConfig,
+ colorManagementConfig, surfaceConfig);
+ }
+ }
+ } else { // (downscale is false)
+ if (blendAnimation) {
+ if (deinterlace) {
+ pipe = MakePipe(swizzleConfig, deinterlacingConfig,
+ colorManagementConfig, blendAnimationConfig,
+ surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(swizzleConfig, interpolatingConfig,
+ colorManagementConfig, blendAnimationConfig,
+ surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(swizzleConfig, colorManagementConfig,
+ blendAnimationConfig, surfaceConfig);
+ }
+ } else if (removeFrameRect) {
+ if (deinterlace) {
+ pipe = MakePipe(swizzleConfig, deinterlacingConfig,
+ colorManagementConfig, removeFrameRectConfig,
+ surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(swizzleConfig, interpolatingConfig,
+ colorManagementConfig, removeFrameRectConfig,
+ surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(swizzleConfig, colorManagementConfig,
+ removeFrameRectConfig, surfaceConfig);
+ }
+ } else { // (blendAnimation and removeFrameRect is false)
+ if (deinterlace) {
+ pipe = MakePipe(swizzleConfig, deinterlacingConfig,
+ colorManagementConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(swizzleConfig, interpolatingConfig,
+ colorManagementConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe =
+ MakePipe(swizzleConfig, colorManagementConfig, surfaceConfig);
+ }
+ }
+ }
+ } else { // (colorManagement is false)
+ if (downscale) {
+ MOZ_ASSERT(!blendAnimation);
+ if (removeFrameRect) {
+ if (deinterlace) {
+ pipe = MakePipe(swizzleConfig, deinterlacingConfig,
+ removeFrameRectConfig, downscalingConfig,
+ surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(swizzleConfig, interpolatingConfig,
+ removeFrameRectConfig, downscalingConfig,
+ surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(swizzleConfig, removeFrameRectConfig,
+ downscalingConfig, surfaceConfig);
+ }
+ } else { // (removeFrameRect is false)
+ if (deinterlace) {
+ pipe = MakePipe(swizzleConfig, deinterlacingConfig,
+ downscalingConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(swizzleConfig, interpolatingConfig,
+ downscalingConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(swizzleConfig, downscalingConfig, surfaceConfig);
+ }
+ }
+ } else { // (downscale is false)
+ if (blendAnimation) {
+ if (deinterlace) {
+ pipe = MakePipe(swizzleConfig, deinterlacingConfig,
+ blendAnimationConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(swizzleConfig, interpolatingConfig,
+ blendAnimationConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe =
+ MakePipe(swizzleConfig, blendAnimationConfig, surfaceConfig);
+ }
+ } else if (removeFrameRect) {
+ if (deinterlace) {
+ pipe = MakePipe(swizzleConfig, deinterlacingConfig,
+ removeFrameRectConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(swizzleConfig, interpolatingConfig,
+ removeFrameRectConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe =
+ MakePipe(swizzleConfig, removeFrameRectConfig, surfaceConfig);
+ }
+ } else { // (blendAnimation and removeFrameRect is false)
+ if (deinterlace) {
+ pipe =
+ MakePipe(swizzleConfig, deinterlacingConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe =
+ MakePipe(swizzleConfig, interpolatingConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(swizzleConfig, surfaceConfig);
+ }
+ }
+ }
+ }
+ } else if (swapOrAlphaSwizzle) {
+ if (colorManagement) {
+ if (downscale) {
+ MOZ_ASSERT(!blendAnimation);
+ if (removeFrameRect) {
+ if (deinterlace) {
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ deinterlacingConfig, removeFrameRectConfig,
+ downscalingConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ interpolatingConfig, removeFrameRectConfig,
+ downscalingConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ removeFrameRectConfig, downscalingConfig,
+ surfaceConfig);
+ }
+ } else { // (removeFrameRect is false)
+ if (deinterlace) {
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ deinterlacingConfig, downscalingConfig,
+ surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ interpolatingConfig, downscalingConfig,
+ surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ downscalingConfig, surfaceConfig);
+ }
+ }
+ } else { // (downscale is false)
+ if (blendAnimation) {
+ if (deinterlace) {
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ deinterlacingConfig, blendAnimationConfig,
+ surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ interpolatingConfig, blendAnimationConfig,
+ surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ blendAnimationConfig, surfaceConfig);
+ }
+ } else if (removeFrameRect) {
+ if (deinterlace) {
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ deinterlacingConfig, removeFrameRectConfig,
+ surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ interpolatingConfig, removeFrameRectConfig,
+ surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ removeFrameRectConfig, surfaceConfig);
+ }
+ } else { // (blendAnimation and removeFrameRect is false)
+ if (deinterlace) {
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ deinterlacingConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(colorManagementConfig, swizzleConfig,
+ interpolatingConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe =
+ MakePipe(colorManagementConfig, swizzleConfig, surfaceConfig);
+ }
+ }
+ }
+ } else { // (colorManagement is false)
+ if (downscale) {
+ MOZ_ASSERT(!blendAnimation);
+ if (removeFrameRect) {
+ if (deinterlace) {
+ pipe = MakePipe(swizzleConfig, deinterlacingConfig,
+ removeFrameRectConfig, downscalingConfig,
+ surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(swizzleConfig, interpolatingConfig,
+ removeFrameRectConfig, downscalingConfig,
+ surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(swizzleConfig, removeFrameRectConfig,
+ downscalingConfig, surfaceConfig);
+ }
+ } else { // (removeFrameRect is false)
+ if (deinterlace) {
+ pipe = MakePipe(swizzleConfig, deinterlacingConfig,
+ downscalingConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(swizzleConfig, interpolatingConfig,
+ downscalingConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(swizzleConfig, downscalingConfig, surfaceConfig);
+ }
+ }
+ } else { // (downscale is false)
+ if (blendAnimation) {
+ if (deinterlace) {
+ pipe = MakePipe(swizzleConfig, deinterlacingConfig,
+ blendAnimationConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(swizzleConfig, interpolatingConfig,
+ blendAnimationConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe =
+ MakePipe(swizzleConfig, blendAnimationConfig, surfaceConfig);
+ }
+ } else if (removeFrameRect) {
+ if (deinterlace) {
+ pipe = MakePipe(swizzleConfig, deinterlacingConfig,
+ removeFrameRectConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(swizzleConfig, interpolatingConfig,
+ removeFrameRectConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe =
+ MakePipe(swizzleConfig, removeFrameRectConfig, surfaceConfig);
+ }
+ } else { // (blendAnimation and removeFrameRect is false)
+ if (deinterlace) {
+ pipe =
+ MakePipe(swizzleConfig, deinterlacingConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe =
+ MakePipe(swizzleConfig, interpolatingConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(swizzleConfig, surfaceConfig);
+ }
+ }
+ }
+ }
+ } else { // (unpackOrMaskSwizzle and swapOrAlphaSwizzle are false)
+ if (colorManagement) {
+ if (downscale) {
+ MOZ_ASSERT(!blendAnimation);
+ if (removeFrameRect) {
+ if (deinterlace) {
+ pipe = MakePipe(deinterlacingConfig, removeFrameRectConfig,
+ downscalingConfig, colorManagementConfig,
+ surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(interpolatingConfig, removeFrameRectConfig,
+ downscalingConfig, colorManagementConfig,
+ surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(removeFrameRectConfig, downscalingConfig,
+ colorManagementConfig, surfaceConfig);
+ }
+ } else { // (removeFrameRect is false)
+ if (deinterlace) {
+ pipe = MakePipe(deinterlacingConfig, downscalingConfig,
+ colorManagementConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(interpolatingConfig, downscalingConfig,
+ colorManagementConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(downscalingConfig, colorManagementConfig,
+ surfaceConfig);
+ }
+ }
+ } else { // (downscale is false)
+ if (blendAnimation) {
+ if (deinterlace) {
+ pipe = MakePipe(deinterlacingConfig, colorManagementConfig,
+ blendAnimationConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(interpolatingConfig, colorManagementConfig,
+ blendAnimationConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(colorManagementConfig, blendAnimationConfig,
+ surfaceConfig);
+ }
+ } else if (removeFrameRect) {
+ if (deinterlace) {
+ pipe = MakePipe(deinterlacingConfig, colorManagementConfig,
+ removeFrameRectConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(interpolatingConfig, colorManagementConfig,
+ removeFrameRectConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(colorManagementConfig, removeFrameRectConfig,
+ surfaceConfig);
+ }
+ } else { // (blendAnimation and removeFrameRect is false)
+ if (deinterlace) {
+ pipe = MakePipe(deinterlacingConfig, colorManagementConfig,
+ surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(interpolatingConfig, colorManagementConfig,
+ surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(colorManagementConfig, surfaceConfig);
+ }
+ }
+ }
+ } else { // (colorManagement is false)
+ if (downscale) {
+ MOZ_ASSERT(!blendAnimation);
+ if (removeFrameRect) {
+ if (deinterlace) {
+ pipe = MakePipe(deinterlacingConfig, removeFrameRectConfig,
+ downscalingConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(interpolatingConfig, removeFrameRectConfig,
+ downscalingConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(removeFrameRectConfig, downscalingConfig,
+ surfaceConfig);
+ }
+ } else { // (removeFrameRect is false)
+ if (deinterlace) {
+ pipe = MakePipe(deinterlacingConfig, downscalingConfig,
+ surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(interpolatingConfig, downscalingConfig,
+ surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(downscalingConfig, surfaceConfig);
+ }
+ }
+ } else { // (downscale is false)
+ if (blendAnimation) {
+ if (deinterlace) {
+ pipe = MakePipe(deinterlacingConfig, blendAnimationConfig,
+ surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(interpolatingConfig, blendAnimationConfig,
+ surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(blendAnimationConfig, surfaceConfig);
+ }
+ } else if (removeFrameRect) {
+ if (deinterlace) {
+ pipe = MakePipe(deinterlacingConfig, removeFrameRectConfig,
+ surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(interpolatingConfig, removeFrameRectConfig,
+ surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(removeFrameRectConfig, surfaceConfig);
+ }
+ } else { // (blendAnimation and removeFrameRect is false)
+ if (deinterlace) {
+ pipe = MakePipe(deinterlacingConfig, surfaceConfig);
+ } else if (adam7Interpolate) {
+ pipe = MakePipe(interpolatingConfig, surfaceConfig);
+ } else { // (deinterlace and adam7Interpolate are false)
+ pipe = MakePipe(surfaceConfig);
+ }
+ }
+ }
+ }
+ }
+
+ return pipe;
+ }
+
+ /**
+ * Creates and initializes a reorienting SurfacePipe.
+ *
+ * @param aDecoder The decoder whose current frame the SurfacePipe will write
+ * to.
+ * @param aInputSize The original size of the image.
+ * @param aOutputSize The size the SurfacePipe should output. Must be the same
+ * as @aInputSize or smaller. If smaller, the image will be
+ * downscaled during decoding.
+ * @param aFormat The surface format of the image; generally B8G8R8A8 or
+ * B8G8R8X8.
+ * @param aOrientation The orientation of the image.
+ *
+ * @return A SurfacePipe if the parameters allowed one to be created
+ * successfully, or Nothing() if the SurfacePipe could not be
+ * initialized.
+ */
+ static Maybe<SurfacePipe> CreateReorientSurfacePipe(
+ Decoder* aDecoder, const OrientedIntSize& aInputSize,
+ const OrientedIntSize& aOutputSize, gfx::SurfaceFormat aFormat,
+ qcms_transform* aTransform, const Orientation& aOrientation) {
+ const bool downscale = aInputSize != aOutputSize;
+ const bool colorManagement = aTransform != nullptr;
+
+ // Construct configurations for the SurfaceFilters. Note that the order of
+ // these filters is significant. We want to deinterlace or interpolate raw
+ // input rows, before any other transformations, and we want to remove the
+ // frame rect (which may involve adding blank rows or columns to the image)
+ // before any downscaling, so that the new rows and columns are taken into
+ // account.
+ DownscalingConfig downscalingConfig{
+ aOrientation.ToUnoriented(aInputSize).ToUnknownSize(), aFormat};
+ ColorManagementConfig colorManagementConfig{aTransform};
+ SurfaceConfig surfaceConfig{aDecoder, aOutputSize.ToUnknownSize(), aFormat,
+ /* mFlipVertically */ false,
+ /* mAnimParams */ Nothing()};
+ ReorientSurfaceConfig reorientSurfaceConfig{aDecoder, aOutputSize, aFormat,
+ aOrientation};
+
+ Maybe<SurfacePipe> pipe;
+
+ if (aOrientation.IsIdentity()) {
+ if (colorManagement) {
+ if (downscale) {
+ pipe =
+ MakePipe(downscalingConfig, colorManagementConfig, surfaceConfig);
+ } else { // (downscale is false)
+ pipe = MakePipe(colorManagementConfig, surfaceConfig);
+ }
+ } else { // (colorManagement is false)
+ if (downscale) {
+ pipe = MakePipe(downscalingConfig, surfaceConfig);
+ } else { // (downscale is false)
+ pipe = MakePipe(surfaceConfig);
+ }
+ }
+ } else { // (orientation is not identity)
+ if (colorManagement) {
+ if (downscale) {
+ pipe = MakePipe(downscalingConfig, colorManagementConfig,
+ reorientSurfaceConfig);
+ } else { // (downscale is false)
+ pipe = MakePipe(colorManagementConfig, reorientSurfaceConfig);
+ }
+ } else { // (colorManagement is false)
+ if (downscale) {
+ pipe = MakePipe(downscalingConfig, reorientSurfaceConfig);
+ } else { // (downscale is false)
+ pipe = MakePipe(reorientSurfaceConfig);
+ }
+ }
+ }
+
+ return pipe;
+ }
+
+ private:
+ template <typename... Configs>
+ static Maybe<SurfacePipe> MakePipe(const Configs&... aConfigs) {
+ auto pipe = MakeUnique<typename detail::FilterPipeline<Configs...>::Type>();
+ nsresult rv = pipe->Configure(aConfigs...);
+ if (NS_FAILED(rv)) {
+ return Nothing();
+ }
+
+ return Some(SurfacePipe{std::move(pipe)});
+ }
+
+ virtual ~SurfacePipeFactory() = 0;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_SurfacePipeFactory_h
diff --git a/image/VectorImage.cpp b/image/VectorImage.cpp
new file mode 100644
index 0000000000..dbef371306
--- /dev/null
+++ b/image/VectorImage.cpp
@@ -0,0 +1,1642 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "VectorImage.h"
+
+#include "AutoRestoreSVGState.h"
+#include "gfx2DGlue.h"
+#include "gfxContext.h"
+#include "gfxDrawable.h"
+#include "gfxPlatform.h"
+#include "gfxUtils.h"
+#include "imgFrame.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/MediaFeatureChange.h"
+#include "mozilla/dom/Event.h"
+#include "mozilla/dom/SVGSVGElement.h"
+#include "mozilla/dom/SVGDocument.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/PendingAnimationTracker.h"
+#include "mozilla/PresShell.h"
+#include "mozilla/ProfilerLabels.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/StaticPrefs_image.h"
+#include "mozilla/SVGObserverUtils.h" // for SVGRenderingObserver
+
+#include "nsIStreamListener.h"
+#include "nsMimeTypes.h"
+#include "nsPresContext.h"
+#include "nsRect.h"
+#include "nsString.h"
+#include "nsStubDocumentObserver.h"
+#include "nsWindowSizes.h"
+#include "ImageRegion.h"
+#include "ISurfaceProvider.h"
+#include "LookupResult.h"
+#include "Orientation.h"
+#include "SVGDocumentWrapper.h"
+#include "SVGDrawingCallback.h"
+#include "SVGDrawingParameters.h"
+#include "nsIDOMEventListener.h"
+#include "SurfaceCache.h"
+#include "BlobSurfaceProvider.h"
+#include "mozilla/dom/Document.h"
+#include "mozilla/dom/DocumentInlines.h"
+#include "mozilla/image/Resolution.h"
+#include "WindowRenderer.h"
+
+namespace mozilla {
+
+using namespace dom;
+using namespace dom::SVGPreserveAspectRatio_Binding;
+using namespace gfx;
+using namespace layers;
+
+namespace image {
+
+// Helper-class: SVGRootRenderingObserver
+class SVGRootRenderingObserver final : public SVGRenderingObserver {
+ public:
+ NS_DECL_ISUPPORTS
+
+ SVGRootRenderingObserver(SVGDocumentWrapper* aDocWrapper,
+ VectorImage* aVectorImage)
+ : SVGRenderingObserver(),
+ mDocWrapper(aDocWrapper),
+ mVectorImage(aVectorImage),
+ mHonoringInvalidations(true) {
+ MOZ_ASSERT(mDocWrapper, "Need a non-null SVG document wrapper");
+ MOZ_ASSERT(mVectorImage, "Need a non-null VectorImage");
+
+ StartObserving();
+ Element* elem = GetReferencedElementWithoutObserving();
+ MOZ_ASSERT(elem, "no root SVG node for us to observe");
+
+ SVGObserverUtils::AddRenderingObserver(elem, this);
+ mInObserverSet = true;
+ }
+
+ void ResumeHonoringInvalidations() { mHonoringInvalidations = true; }
+
+ protected:
+ virtual ~SVGRootRenderingObserver() {
+ // This needs to call our GetReferencedElementWithoutObserving override,
+ // so must be called here rather than in our base class's dtor.
+ StopObserving();
+ }
+
+ Element* GetReferencedElementWithoutObserving() final {
+ return mDocWrapper->GetRootSVGElem();
+ }
+
+ virtual void OnRenderingChange() override {
+ Element* elem = GetReferencedElementWithoutObserving();
+ MOZ_ASSERT(elem, "missing root SVG node");
+
+ if (mHonoringInvalidations && !mDocWrapper->ShouldIgnoreInvalidation()) {
+ nsIFrame* frame = elem->GetPrimaryFrame();
+ if (!frame || frame->PresShell()->IsDestroying()) {
+ // We're being destroyed. Bail out.
+ return;
+ }
+
+ // Ignore further invalidations until we draw.
+ mHonoringInvalidations = false;
+
+ mVectorImage->InvalidateObserversOnNextRefreshDriverTick();
+ }
+
+ // Our caller might've removed us from rendering-observer list.
+ // Add ourselves back!
+ if (!mInObserverSet) {
+ SVGObserverUtils::AddRenderingObserver(elem, this);
+ mInObserverSet = true;
+ }
+ }
+
+ // Private data
+ const RefPtr<SVGDocumentWrapper> mDocWrapper;
+ VectorImage* const mVectorImage; // Raw pointer because it owns me.
+ bool mHonoringInvalidations;
+};
+
+NS_IMPL_ISUPPORTS(SVGRootRenderingObserver, nsIMutationObserver)
+
+class SVGParseCompleteListener final : public nsStubDocumentObserver {
+ public:
+ NS_DECL_ISUPPORTS
+
+ SVGParseCompleteListener(SVGDocument* aDocument, VectorImage* aImage)
+ : mDocument(aDocument), mImage(aImage) {
+ MOZ_ASSERT(mDocument, "Need an SVG document");
+ MOZ_ASSERT(mImage, "Need an image");
+
+ mDocument->AddObserver(this);
+ }
+
+ private:
+ ~SVGParseCompleteListener() {
+ if (mDocument) {
+ // The document must have been destroyed before we got our event.
+ // Otherwise this can't happen, since documents hold strong references to
+ // their observers.
+ Cancel();
+ }
+ }
+
+ public:
+ void EndLoad(Document* aDocument) override {
+ MOZ_ASSERT(aDocument == mDocument, "Got EndLoad for wrong document?");
+
+ // OnSVGDocumentParsed will release our owner's reference to us, so ensure
+ // we stick around long enough to complete our work.
+ RefPtr<SVGParseCompleteListener> kungFuDeathGrip(this);
+
+ mImage->OnSVGDocumentParsed();
+ }
+
+ void Cancel() {
+ MOZ_ASSERT(mDocument, "Duplicate call to Cancel");
+ if (mDocument) {
+ mDocument->RemoveObserver(this);
+ mDocument = nullptr;
+ }
+ }
+
+ private:
+ RefPtr<SVGDocument> mDocument;
+ VectorImage* const mImage; // Raw pointer to owner.
+};
+
+NS_IMPL_ISUPPORTS(SVGParseCompleteListener, nsIDocumentObserver)
+
+class SVGLoadEventListener final : public nsIDOMEventListener {
+ public:
+ NS_DECL_ISUPPORTS
+
+ SVGLoadEventListener(Document* aDocument, VectorImage* aImage)
+ : mDocument(aDocument), mImage(aImage) {
+ MOZ_ASSERT(mDocument, "Need an SVG document");
+ MOZ_ASSERT(mImage, "Need an image");
+
+ mDocument->AddEventListener(u"MozSVGAsImageDocumentLoad"_ns, this, true,
+ false);
+ }
+
+ private:
+ ~SVGLoadEventListener() {
+ if (mDocument) {
+ // The document must have been destroyed before we got our event.
+ // Otherwise this can't happen, since documents hold strong references to
+ // their observers.
+ Cancel();
+ }
+ }
+
+ public:
+ NS_IMETHOD HandleEvent(Event* aEvent) override {
+ MOZ_ASSERT(mDocument, "Need an SVG document. Received multiple events?");
+
+ // OnSVGDocumentLoaded will release our owner's reference
+ // to us, so ensure we stick around long enough to complete our work.
+ RefPtr<SVGLoadEventListener> kungFuDeathGrip(this);
+
+#ifdef DEBUG
+ nsAutoString eventType;
+ aEvent->GetType(eventType);
+ MOZ_ASSERT(eventType.EqualsLiteral("MozSVGAsImageDocumentLoad"),
+ "Received unexpected event");
+#endif
+
+ mImage->OnSVGDocumentLoaded();
+
+ return NS_OK;
+ }
+
+ void Cancel() {
+ MOZ_ASSERT(mDocument, "Duplicate call to Cancel");
+ if (mDocument) {
+ mDocument->RemoveEventListener(u"MozSVGAsImageDocumentLoad"_ns, this,
+ true);
+ mDocument = nullptr;
+ }
+ }
+
+ private:
+ nsCOMPtr<Document> mDocument;
+ VectorImage* const mImage; // Raw pointer to owner.
+};
+
+NS_IMPL_ISUPPORTS(SVGLoadEventListener, nsIDOMEventListener)
+
+SVGDrawingCallback::SVGDrawingCallback(SVGDocumentWrapper* aSVGDocumentWrapper,
+ const IntSize& aViewportSize,
+ const IntSize& aSize,
+ uint32_t aImageFlags)
+ : mSVGDocumentWrapper(aSVGDocumentWrapper),
+ mViewportSize(aViewportSize),
+ mSize(aSize),
+ mImageFlags(aImageFlags) {}
+
+SVGDrawingCallback::~SVGDrawingCallback() = default;
+
+// Based loosely on SVGIntegrationUtils' PaintFrameCallback::operator()
+bool SVGDrawingCallback::operator()(gfxContext* aContext,
+ const gfxRect& aFillRect,
+ const SamplingFilter aSamplingFilter,
+ const gfxMatrix& aTransform) {
+ MOZ_ASSERT(mSVGDocumentWrapper, "need an SVGDocumentWrapper");
+
+ // Get (& sanity-check) the helper-doc's presShell
+ RefPtr<PresShell> presShell = mSVGDocumentWrapper->GetPresShell();
+ MOZ_ASSERT(presShell, "GetPresShell returned null for an SVG image?");
+
+ Document* doc = presShell->GetDocument();
+ [[maybe_unused]] nsIURI* uri = doc ? doc->GetDocumentURI() : nullptr;
+ AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(
+ "SVG Image drawing", GRAPHICS,
+ nsPrintfCString("%dx%d %s", mSize.width, mSize.height,
+ uri ? uri->GetSpecOrDefault().get() : "N/A"));
+
+ gfxContextAutoSaveRestore contextRestorer(aContext);
+
+ // Clip to aFillRect so that we don't paint outside.
+ aContext->Clip(aFillRect);
+
+ gfxMatrix matrix = aTransform;
+ if (!matrix.Invert()) {
+ return false;
+ }
+ aContext->SetMatrixDouble(
+ aContext->CurrentMatrixDouble().PreMultiply(matrix).PreScale(
+ double(mSize.width) / mViewportSize.width,
+ double(mSize.height) / mViewportSize.height));
+
+ nsPresContext* presContext = presShell->GetPresContext();
+ MOZ_ASSERT(presContext, "pres shell w/out pres context");
+
+ nsRect svgRect(0, 0, presContext->DevPixelsToAppUnits(mViewportSize.width),
+ presContext->DevPixelsToAppUnits(mViewportSize.height));
+
+ RenderDocumentFlags renderDocFlags =
+ RenderDocumentFlags::IgnoreViewportScrolling;
+ if (!(mImageFlags & imgIContainer::FLAG_SYNC_DECODE)) {
+ renderDocFlags |= RenderDocumentFlags::AsyncDecodeImages;
+ }
+ if (mImageFlags & imgIContainer::FLAG_HIGH_QUALITY_SCALING) {
+ renderDocFlags |= RenderDocumentFlags::UseHighQualityScaling;
+ }
+
+ presShell->RenderDocument(svgRect, renderDocFlags,
+ NS_RGBA(0, 0, 0, 0), // transparent
+ aContext);
+
+ return true;
+}
+
+// Implement VectorImage's nsISupports-inherited methods
+NS_IMPL_ISUPPORTS(VectorImage, imgIContainer, nsIStreamListener,
+ nsIRequestObserver)
+
+//------------------------------------------------------------------------------
+// Constructor / Destructor
+
+VectorImage::VectorImage(nsIURI* aURI /* = nullptr */)
+ : ImageResource(aURI), // invoke superclass's constructor
+ mLockCount(0),
+ mIsInitialized(false),
+ mDiscardable(false),
+ mIsFullyLoaded(false),
+ mHaveAnimations(false),
+ mHasPendingInvalidation(false) {}
+
+VectorImage::~VectorImage() {
+ ReportDocumentUseCounters();
+ CancelAllListeners();
+ SurfaceCache::RemoveImage(ImageKey(this));
+}
+
+//------------------------------------------------------------------------------
+// Methods inherited from Image.h
+
+nsresult VectorImage::Init(const char* aMimeType, uint32_t aFlags) {
+ // We don't support re-initialization
+ if (mIsInitialized) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ MOZ_ASSERT(!mIsFullyLoaded && !mHaveAnimations && !mError,
+ "Flags unexpectedly set before initialization");
+ MOZ_ASSERT(!strcmp(aMimeType, IMAGE_SVG_XML), "Unexpected mimetype");
+
+ mDiscardable = !!(aFlags & INIT_FLAG_DISCARDABLE);
+
+ // Lock this image's surfaces in the SurfaceCache if we're not discardable.
+ if (!mDiscardable) {
+ mLockCount++;
+ SurfaceCache::LockImage(ImageKey(this));
+ }
+
+ mIsInitialized = true;
+ return NS_OK;
+}
+
+size_t VectorImage::SizeOfSourceWithComputedFallback(
+ SizeOfState& aState) const {
+ if (!mSVGDocumentWrapper) {
+ return 0; // No document, so no memory used for the document.
+ }
+
+ SVGDocument* doc = mSVGDocumentWrapper->GetDocument();
+ if (!doc) {
+ return 0; // No document, so no memory used for the document.
+ }
+
+ nsWindowSizes windowSizes(aState);
+ doc->DocAddSizeOfIncludingThis(windowSizes);
+
+ if (windowSizes.getTotalSize() == 0) {
+ // MallocSizeOf fails on this platform. Because we also use this method for
+ // determining the size of cache entries, we need to return something
+ // reasonable here. Unfortunately, there's no way to estimate the document's
+ // size accurately, so we just use a constant value of 100KB, which will
+ // generally underestimate the true size.
+ return 100 * 1024;
+ }
+
+ return windowSizes.getTotalSize();
+}
+
+nsresult VectorImage::OnImageDataComplete(nsIRequest* aRequest,
+ nsresult aStatus, bool aLastPart) {
+ // Call our internal OnStopRequest method, which only talks to our embedded
+ // SVG document. This won't have any effect on our ProgressTracker.
+ nsresult finalStatus = OnStopRequest(aRequest, aStatus);
+
+ // Give precedence to Necko failure codes.
+ if (NS_FAILED(aStatus)) {
+ finalStatus = aStatus;
+ }
+
+ Progress loadProgress = LoadCompleteProgress(aLastPart, mError, finalStatus);
+
+ if (mIsFullyLoaded || mError) {
+ // Our document is loaded, so we're ready to notify now.
+ mProgressTracker->SyncNotifyProgress(loadProgress);
+ } else {
+ // Record our progress so far; we'll actually send the notifications in
+ // OnSVGDocumentLoaded or OnSVGDocumentError.
+ mLoadProgress = Some(loadProgress);
+ }
+
+ return finalStatus;
+}
+
+nsresult VectorImage::OnImageDataAvailable(nsIRequest* aRequest,
+ nsIInputStream* aInStr,
+ uint64_t aSourceOffset,
+ uint32_t aCount) {
+ return OnDataAvailable(aRequest, aInStr, aSourceOffset, aCount);
+}
+
+nsresult VectorImage::StartAnimation() {
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ MOZ_ASSERT(ShouldAnimate(), "Should not animate!");
+
+ mSVGDocumentWrapper->StartAnimation();
+ return NS_OK;
+}
+
+nsresult VectorImage::StopAnimation() {
+ nsresult rv = NS_OK;
+ if (mError) {
+ rv = NS_ERROR_FAILURE;
+ } else {
+ MOZ_ASSERT(mIsFullyLoaded && mHaveAnimations,
+ "Should not have been animating!");
+
+ mSVGDocumentWrapper->StopAnimation();
+ }
+
+ mAnimating = false;
+ return rv;
+}
+
+bool VectorImage::ShouldAnimate() {
+ return ImageResource::ShouldAnimate() && mIsFullyLoaded && mHaveAnimations;
+}
+
+NS_IMETHODIMP_(void)
+VectorImage::SetAnimationStartTime(const TimeStamp& aTime) {
+ // We don't care about animation start time.
+}
+
+//------------------------------------------------------------------------------
+// imgIContainer methods
+
+//******************************************************************************
+NS_IMETHODIMP
+VectorImage::GetWidth(int32_t* aWidth) {
+ if (mError || !mIsFullyLoaded) {
+ // XXXdholbert Technically we should leave outparam untouched when we
+ // fail. But since many callers don't check for failure, we set it to 0 on
+ // failure, for sane/predictable results.
+ *aWidth = 0;
+ return NS_ERROR_FAILURE;
+ }
+
+ SVGSVGElement* rootElem = mSVGDocumentWrapper->GetRootSVGElem();
+ MOZ_ASSERT(rootElem,
+ "Should have a root SVG elem, since we finished "
+ "loading without errors");
+ int32_t rootElemWidth = rootElem->GetIntrinsicWidth();
+ if (rootElemWidth < 0) {
+ *aWidth = 0;
+ return NS_ERROR_FAILURE;
+ }
+ *aWidth = rootElemWidth;
+ return NS_OK;
+}
+
+//******************************************************************************
+nsresult VectorImage::GetNativeSizes(nsTArray<IntSize>& aNativeSizes) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+size_t VectorImage::GetNativeSizesLength() { return 0; }
+
+//******************************************************************************
+NS_IMETHODIMP_(void)
+VectorImage::RequestRefresh(const TimeStamp& aTime) {
+ if (HadRecentRefresh(aTime)) {
+ return;
+ }
+
+ Document* doc = mSVGDocumentWrapper->GetDocument();
+ if (!doc) {
+ // We are racing between shutdown and a refresh.
+ return;
+ }
+
+ PendingAnimationTracker* tracker = doc->GetPendingAnimationTracker();
+ if (tracker && ShouldAnimate()) {
+ tracker->TriggerPendingAnimationsOnNextTick(aTime);
+ }
+
+ EvaluateAnimation();
+
+ mSVGDocumentWrapper->TickRefreshDriver();
+
+ if (mHasPendingInvalidation) {
+ SendInvalidationNotifications();
+ }
+}
+
+void VectorImage::SendInvalidationNotifications() {
+ // Animated images don't send out invalidation notifications as soon as
+ // they're generated. Instead, InvalidateObserversOnNextRefreshDriverTick
+ // records that there are pending invalidations and then returns immediately.
+ // The notifications are actually sent from RequestRefresh(). We send these
+ // notifications there to ensure that there is actually a document observing
+ // us. Otherwise, the notifications are just wasted effort.
+ //
+ // Non-animated images post an event to call this method from
+ // InvalidateObserversOnNextRefreshDriverTick, because RequestRefresh is never
+ // called for them. Ordinarily this isn't needed, since we send out
+ // invalidation notifications in OnSVGDocumentLoaded, but in rare cases the
+ // SVG document may not be 100% ready to render at that time. In those cases
+ // we would miss the subsequent invalidations if we didn't send out the
+ // notifications indirectly in |InvalidateObservers...|.
+
+ mHasPendingInvalidation = false;
+
+ if (SurfaceCache::InvalidateImage(ImageKey(this))) {
+ // If we still have recordings in the cache, make sure we handle future
+ // invalidations.
+ MOZ_ASSERT(mRenderingObserver, "Should have a rendering observer by now");
+ mRenderingObserver->ResumeHonoringInvalidations();
+ }
+
+ if (mProgressTracker) {
+ mProgressTracker->SyncNotifyProgress(FLAG_FRAME_COMPLETE,
+ GetMaxSizedIntRect());
+ }
+}
+
+NS_IMETHODIMP_(IntRect)
+VectorImage::GetImageSpaceInvalidationRect(const IntRect& aRect) {
+ return aRect;
+}
+
+//******************************************************************************
+NS_IMETHODIMP
+VectorImage::GetHeight(int32_t* aHeight) {
+ if (mError || !mIsFullyLoaded) {
+ // XXXdholbert Technically we should leave outparam untouched when we
+ // fail. But since many callers don't check for failure, we set it to 0 on
+ // failure, for sane/predictable results.
+ *aHeight = 0;
+ return NS_ERROR_FAILURE;
+ }
+
+ SVGSVGElement* rootElem = mSVGDocumentWrapper->GetRootSVGElem();
+ MOZ_ASSERT(rootElem,
+ "Should have a root SVG elem, since we finished "
+ "loading without errors");
+ int32_t rootElemHeight = rootElem->GetIntrinsicHeight();
+ if (rootElemHeight < 0) {
+ *aHeight = 0;
+ return NS_ERROR_FAILURE;
+ }
+ *aHeight = rootElemHeight;
+ return NS_OK;
+}
+
+//******************************************************************************
+NS_IMETHODIMP
+VectorImage::GetIntrinsicSize(nsSize* aSize) {
+ if (mError || !mIsFullyLoaded) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsIFrame* rootFrame = mSVGDocumentWrapper->GetRootLayoutFrame();
+ if (!rootFrame) {
+ return NS_ERROR_FAILURE;
+ }
+
+ *aSize = nsSize(-1, -1);
+ IntrinsicSize rfSize = rootFrame->GetIntrinsicSize();
+ if (rfSize.width) {
+ aSize->width = *rfSize.width;
+ }
+ if (rfSize.height) {
+ aSize->height = *rfSize.height;
+ }
+ return NS_OK;
+}
+
+//******************************************************************************
+Maybe<AspectRatio> VectorImage::GetIntrinsicRatio() {
+ if (mError || !mIsFullyLoaded) {
+ return Nothing();
+ }
+
+ nsIFrame* rootFrame = mSVGDocumentWrapper->GetRootLayoutFrame();
+ if (!rootFrame) {
+ return Nothing();
+ }
+
+ return Some(rootFrame->GetIntrinsicRatio());
+}
+
+NS_IMETHODIMP_(Orientation)
+VectorImage::GetOrientation() { return Orientation(); }
+
+NS_IMETHODIMP_(Resolution)
+VectorImage::GetResolution() { return {}; }
+
+//******************************************************************************
+NS_IMETHODIMP
+VectorImage::GetType(uint16_t* aType) {
+ NS_ENSURE_ARG_POINTER(aType);
+
+ *aType = imgIContainer::TYPE_VECTOR;
+ return NS_OK;
+}
+
+//******************************************************************************
+NS_IMETHODIMP
+VectorImage::GetProviderId(uint32_t* aId) {
+ NS_ENSURE_ARG_POINTER(aId);
+
+ *aId = ImageResource::GetImageProviderId();
+ return NS_OK;
+}
+
+//******************************************************************************
+NS_IMETHODIMP
+VectorImage::GetAnimated(bool* aAnimated) {
+ if (mError || !mIsFullyLoaded) {
+ return NS_ERROR_FAILURE;
+ }
+
+ *aAnimated = mSVGDocumentWrapper->IsAnimated();
+ return NS_OK;
+}
+
+//******************************************************************************
+int32_t VectorImage::GetFirstFrameDelay() {
+ if (mError) {
+ return -1;
+ }
+
+ if (!mSVGDocumentWrapper->IsAnimated()) {
+ return -1;
+ }
+
+ // We don't really have a frame delay, so just pretend that we constantly
+ // need updates.
+ return 0;
+}
+
+NS_IMETHODIMP_(bool)
+VectorImage::WillDrawOpaqueNow() {
+ return false; // In general, SVG content is not opaque.
+}
+
+//******************************************************************************
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+VectorImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) {
+ if (mError) {
+ return nullptr;
+ }
+
+ // Look up height & width
+ // ----------------------
+ SVGSVGElement* svgElem = mSVGDocumentWrapper->GetRootSVGElem();
+ MOZ_ASSERT(svgElem,
+ "Should have a root SVG elem, since we finished "
+ "loading without errors");
+ nsIntSize imageIntSize(svgElem->GetIntrinsicWidth(),
+ svgElem->GetIntrinsicHeight());
+
+ if (imageIntSize.IsEmpty()) {
+ // We'll get here if our SVG doc has a percent-valued or negative width or
+ // height.
+ return nullptr;
+ }
+
+ return GetFrameAtSize(imageIntSize, aWhichFrame, aFlags);
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+VectorImage::GetFrameAtSize(const IntSize& aSize, uint32_t aWhichFrame,
+ uint32_t aFlags) {
+ MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
+
+ AutoProfilerImagePaintMarker PROFILER_RAII(this);
+#ifdef DEBUG
+ NotifyDrawingObservers();
+#endif
+
+ if (aSize.IsEmpty() || aWhichFrame > FRAME_MAX_VALUE || mError ||
+ !mIsFullyLoaded) {
+ return nullptr;
+ }
+
+ uint32_t whichFrame = mHaveAnimations ? aWhichFrame : FRAME_FIRST;
+
+ auto [sourceSurface, decodeSize] =
+ LookupCachedSurface(aSize, SVGImageContext(), aFlags);
+ if (sourceSurface) {
+ return sourceSurface.forget();
+ }
+
+ if (mSVGDocumentWrapper->IsDrawing()) {
+ NS_WARNING("Refusing to make re-entrant call to VectorImage::Draw");
+ return nullptr;
+ }
+
+ float animTime = (whichFrame == FRAME_FIRST)
+ ? 0.0f
+ : mSVGDocumentWrapper->GetCurrentTimeAsFloat();
+
+ // By using a null gfxContext, we ensure that we will always attempt to
+ // create a surface, even if we aren't capable of caching it (e.g. due to our
+ // flags, having an animation, etc). Otherwise CreateSurface will assume that
+ // the caller is capable of drawing directly to its own draw target if we
+ // cannot cache.
+ SVGImageContext svgContext;
+ SVGDrawingParameters params(
+ nullptr, decodeSize, aSize, ImageRegion::Create(decodeSize),
+ SamplingFilter::POINT, svgContext, animTime, aFlags, 1.0);
+
+ bool didCache; // Was the surface put into the cache?
+
+ AutoRestoreSVGState autoRestore(params, mSVGDocumentWrapper,
+ /* aContextPaint */ false);
+
+ RefPtr<gfxDrawable> svgDrawable = CreateSVGDrawable(params);
+ RefPtr<SourceSurface> surface = CreateSurface(params, svgDrawable, didCache);
+ if (!surface) {
+ MOZ_ASSERT(!didCache);
+ return nullptr;
+ }
+
+ SendFrameComplete(didCache, params.flags);
+ return surface.forget();
+}
+
+NS_IMETHODIMP_(bool)
+VectorImage::IsImageContainerAvailable(WindowRenderer* aRenderer,
+ uint32_t aFlags) {
+ if (mError || !mIsFullyLoaded ||
+ aRenderer->GetBackendType() != LayersBackend::LAYERS_WR) {
+ return false;
+ }
+
+ if (mHaveAnimations && !StaticPrefs::image_svg_blob_image()) {
+ // We don't support rasterizing animation SVGs. We can put them in a blob
+ // recording however instead of using fallback.
+ return false;
+ }
+
+ return true;
+}
+
+//******************************************************************************
+NS_IMETHODIMP_(ImgDrawResult)
+VectorImage::GetImageProvider(WindowRenderer* aRenderer,
+ const gfx::IntSize& aSize,
+ const SVGImageContext& aSVGContext,
+ const Maybe<ImageIntRegion>& aRegion,
+ uint32_t aFlags,
+ WebRenderImageProvider** aProvider) {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(aRenderer);
+ MOZ_ASSERT(!(aFlags & FLAG_BYPASS_SURFACE_CACHE), "Unsupported flags");
+
+ // We don't need to check if the size is too big since we only support
+ // WebRender backends.
+ if (aSize.IsEmpty()) {
+ return ImgDrawResult::BAD_ARGS;
+ }
+
+ if (mError) {
+ return ImgDrawResult::BAD_IMAGE;
+ }
+
+ if (!mIsFullyLoaded) {
+ return ImgDrawResult::NOT_READY;
+ }
+
+ if (mHaveAnimations && !(aFlags & FLAG_RECORD_BLOB)) {
+ // We don't support rasterizing animation SVGs. We can put them in a blob
+ // recording however instead of using fallback.
+ return ImgDrawResult::NOT_SUPPORTED;
+ }
+
+ AutoProfilerImagePaintMarker PROFILER_RAII(this);
+#ifdef DEBUG
+ NotifyDrawingObservers();
+#endif
+
+ // Only blob recordings support a region to restrict drawing.
+ const bool blobRecording = aFlags & FLAG_RECORD_BLOB;
+ MOZ_ASSERT_IF(!blobRecording, aRegion.isNothing());
+
+ LookupResult result(MatchType::NOT_FOUND);
+ auto playbackType =
+ mHaveAnimations ? PlaybackType::eAnimated : PlaybackType::eStatic;
+ auto surfaceFlags = ToSurfaceFlags(aFlags);
+
+ SurfaceKey surfaceKey =
+ VectorSurfaceKey(aSize, aRegion, aSVGContext, surfaceFlags, playbackType);
+ if ((aFlags & FLAG_SYNC_DECODE) || !(aFlags & FLAG_HIGH_QUALITY_SCALING)) {
+ result = SurfaceCache::Lookup(ImageKey(this), surfaceKey,
+ /* aMarkUsed = */ true);
+ } else {
+ result = SurfaceCache::LookupBestMatch(ImageKey(this), surfaceKey,
+ /* aMarkUsed = */ true);
+ }
+
+ // Unless we get a best match (exact or factor of 2 limited), then we want to
+ // generate a new recording/rerasterize, even if we have a substitute.
+ if (result && (result.Type() == MatchType::EXACT ||
+ result.Type() == MatchType::SUBSTITUTE_BECAUSE_BEST)) {
+ result.Surface().TakeProvider(aProvider);
+ return ImgDrawResult::SUCCESS;
+ }
+
+ // Ensure we store the surface with the correct key if we switched to factor
+ // of 2 sizing or we otherwise got clamped.
+ IntSize rasterSize(aSize);
+ if (!result.SuggestedSize().IsEmpty()) {
+ rasterSize = result.SuggestedSize();
+ surfaceKey = surfaceKey.CloneWithSize(rasterSize);
+ }
+
+ // We're about to rerasterize, which may mean that some of the previous
+ // surfaces we've rasterized aren't useful anymore. We can allow them to
+ // expire from the cache by unlocking them here, and then sending out an
+ // invalidation. If this image is locked, any surfaces that are still useful
+ // will become locked again when Draw touches them, and the remainder will
+ // eventually expire.
+ bool mayCache = SurfaceCache::CanHold(rasterSize);
+ if (mayCache) {
+ SurfaceCache::UnlockEntries(ImageKey(this));
+ }
+
+ // Blob recorded vector images just create a provider responsible for
+ // generating blob keys and recording bindings. The recording won't happen
+ // until the caller requests the key explicitly.
+ RefPtr<ISurfaceProvider> provider;
+ if (blobRecording) {
+ provider = MakeRefPtr<BlobSurfaceProvider>(ImageKey(this), surfaceKey,
+ mSVGDocumentWrapper, aFlags);
+ } else {
+ if (mSVGDocumentWrapper->IsDrawing()) {
+ NS_WARNING("Refusing to make re-entrant call to VectorImage::Draw");
+ return ImgDrawResult::TEMPORARY_ERROR;
+ }
+
+ if (!SurfaceCache::IsLegalSize(rasterSize) ||
+ !Factory::AllowedSurfaceSize(rasterSize)) {
+ // If either of these is true then the InitWithDrawable call below will
+ // fail, so fail early and use this opportunity to return NOT_SUPPORTED
+ // instead of TEMPORARY_ERROR as we do for any InitWithDrawable failure.
+ // This means that we will use fallback which has a path that will draw
+ // directly into the gfxContext without having to allocate a surface. It
+ // means we will have to use fallback and re-rasterize for everytime we
+ // have to draw this image, but it's better than not drawing anything at
+ // all.
+ return ImgDrawResult::NOT_SUPPORTED;
+ }
+
+ // We aren't using blobs, so we need to rasterize.
+ float animTime =
+ mHaveAnimations ? mSVGDocumentWrapper->GetCurrentTimeAsFloat() : 0.0f;
+
+ // By using a null gfxContext, we ensure that we will always attempt to
+ // create a surface, even if we aren't capable of caching it (e.g. due to
+ // our flags, having an animation, etc). Otherwise CreateSurface will assume
+ // that the caller is capable of drawing directly to its own draw target if
+ // we cannot cache.
+ SVGDrawingParameters params(
+ nullptr, rasterSize, aSize, ImageRegion::Create(rasterSize),
+ SamplingFilter::POINT, aSVGContext, animTime, aFlags, 1.0);
+
+ RefPtr<gfxDrawable> svgDrawable = CreateSVGDrawable(params);
+ bool contextPaint = aSVGContext.GetContextPaint();
+ AutoRestoreSVGState autoRestore(params, mSVGDocumentWrapper, contextPaint);
+
+ mSVGDocumentWrapper->UpdateViewportBounds(params.viewportSize);
+ mSVGDocumentWrapper->FlushImageTransformInvalidation();
+
+ // Given we have no context, the default backend is fine.
+ BackendType backend =
+ gfxPlatform::GetPlatform()->GetDefaultContentBackend();
+
+ // Try to create an imgFrame, initializing the surface it contains by
+ // drawing our gfxDrawable into it. (We use FILTER_NEAREST since we never
+ // scale here.)
+ auto frame = MakeNotNull<RefPtr<imgFrame>>();
+ nsresult rv = frame->InitWithDrawable(
+ svgDrawable, params.size, SurfaceFormat::OS_RGBA, SamplingFilter::POINT,
+ params.flags, backend);
+
+ // If we couldn't create the frame, it was probably because it would end
+ // up way too big. Generally it also wouldn't fit in the cache, but the
+ // prefs could be set such that the cache isn't the limiting factor.
+ if (NS_FAILED(rv)) {
+ return ImgDrawResult::TEMPORARY_ERROR;
+ }
+
+ provider =
+ MakeRefPtr<SimpleSurfaceProvider>(ImageKey(this), surfaceKey, frame);
+ }
+
+ if (mayCache) {
+ // Attempt to cache the frame.
+ if (SurfaceCache::Insert(WrapNotNull(provider)) == InsertOutcome::SUCCESS) {
+ if (rasterSize != aSize) {
+ // We created a new surface that wasn't the size we requested, which
+ // means we entered factor-of-2 mode. We should purge any surfaces we
+ // no longer need rather than waiting for the cache to expire them.
+ SurfaceCache::PruneImage(ImageKey(this));
+ }
+
+ SendFrameComplete(/* aDidCache */ true, aFlags);
+ }
+ }
+
+ MOZ_ASSERT(provider);
+ provider.forget(aProvider);
+ return ImgDrawResult::SUCCESS;
+}
+
+bool VectorImage::MaybeRestrictSVGContext(SVGImageContext& aSVGContext,
+ uint32_t aFlags) {
+ bool overridePAR = (aFlags & FLAG_FORCE_PRESERVEASPECTRATIO_NONE);
+
+ bool haveContextPaint = aSVGContext.GetContextPaint();
+ bool blockContextPaint =
+ haveContextPaint && !SVGContextPaint::IsAllowedForImageFromURI(mURI);
+
+ if (overridePAR || blockContextPaint) {
+ if (overridePAR) {
+ // The SVGImageContext must take account of the preserveAspectRatio
+ // override:
+ MOZ_ASSERT(!aSVGContext.GetPreserveAspectRatio(),
+ "FLAG_FORCE_PRESERVEASPECTRATIO_NONE is not expected if a "
+ "preserveAspectRatio override is supplied");
+ Maybe<SVGPreserveAspectRatio> aspectRatio = Some(SVGPreserveAspectRatio(
+ SVG_PRESERVEASPECTRATIO_NONE, SVG_MEETORSLICE_UNKNOWN));
+ aSVGContext.SetPreserveAspectRatio(aspectRatio);
+ }
+
+ if (blockContextPaint) {
+ // The SVGImageContext must not include context paint if the image is
+ // not allowed to use it:
+ aSVGContext.ClearContextPaint();
+ }
+ }
+
+ return haveContextPaint && !blockContextPaint;
+}
+
+//******************************************************************************
+NS_IMETHODIMP_(ImgDrawResult)
+VectorImage::Draw(gfxContext* aContext, const nsIntSize& aSize,
+ const ImageRegion& aRegion, uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ const SVGImageContext& aSVGContext, uint32_t aFlags,
+ float aOpacity) {
+ if (aWhichFrame > FRAME_MAX_VALUE) {
+ return ImgDrawResult::BAD_ARGS;
+ }
+
+ if (!aContext) {
+ return ImgDrawResult::BAD_ARGS;
+ }
+
+ if (mError) {
+ return ImgDrawResult::BAD_IMAGE;
+ }
+
+ if (!mIsFullyLoaded) {
+ return ImgDrawResult::NOT_READY;
+ }
+
+ if (mAnimationConsumers == 0 && mHaveAnimations) {
+ SendOnUnlockedDraw(aFlags);
+ }
+
+ // We should bypass the cache when:
+ // - We are using a DrawTargetRecording because we prefer the drawing commands
+ // in general to the rasterized surface. This allows blob images to avoid
+ // rasterized SVGs with WebRender.
+ if (aContext->GetDrawTarget()->GetBackendType() == BackendType::RECORDING) {
+ aFlags |= FLAG_BYPASS_SURFACE_CACHE;
+ }
+
+ MOZ_ASSERT(!(aFlags & FLAG_FORCE_PRESERVEASPECTRATIO_NONE) ||
+ aSVGContext.GetViewportSize(),
+ "Viewport size is required when using "
+ "FLAG_FORCE_PRESERVEASPECTRATIO_NONE");
+
+ uint32_t whichFrame = mHaveAnimations ? aWhichFrame : FRAME_FIRST;
+
+ float animTime = (whichFrame == FRAME_FIRST)
+ ? 0.0f
+ : mSVGDocumentWrapper->GetCurrentTimeAsFloat();
+
+ SVGImageContext newSVGContext = aSVGContext;
+ bool contextPaint = MaybeRestrictSVGContext(newSVGContext, aFlags);
+
+ SVGDrawingParameters params(aContext, aSize, aSize, aRegion, aSamplingFilter,
+ newSVGContext, animTime, aFlags, aOpacity);
+
+ // If we have an prerasterized version of this image that matches the
+ // drawing parameters, use that.
+ RefPtr<SourceSurface> sourceSurface;
+ std::tie(sourceSurface, params.size) =
+ LookupCachedSurface(aSize, params.svgContext, aFlags);
+ if (sourceSurface) {
+ RefPtr<gfxDrawable> drawable =
+ new gfxSurfaceDrawable(sourceSurface, params.size);
+ Show(drawable, params);
+ return ImgDrawResult::SUCCESS;
+ }
+
+ // else, we need to paint the image:
+
+ if (mSVGDocumentWrapper->IsDrawing()) {
+ NS_WARNING("Refusing to make re-entrant call to VectorImage::Draw");
+ return ImgDrawResult::TEMPORARY_ERROR;
+ }
+
+ AutoRestoreSVGState autoRestore(params, mSVGDocumentWrapper, contextPaint);
+
+ bool didCache; // Was the surface put into the cache?
+ RefPtr<gfxDrawable> svgDrawable = CreateSVGDrawable(params);
+ sourceSurface = CreateSurface(params, svgDrawable, didCache);
+ if (!sourceSurface) {
+ MOZ_ASSERT(!didCache);
+ Show(svgDrawable, params);
+ return ImgDrawResult::SUCCESS;
+ }
+
+ RefPtr<gfxDrawable> drawable =
+ new gfxSurfaceDrawable(sourceSurface, params.size);
+ Show(drawable, params);
+ SendFrameComplete(didCache, params.flags);
+ return ImgDrawResult::SUCCESS;
+}
+
+already_AddRefed<gfxDrawable> VectorImage::CreateSVGDrawable(
+ const SVGDrawingParameters& aParams) {
+ RefPtr<gfxDrawingCallback> cb = new SVGDrawingCallback(
+ mSVGDocumentWrapper, aParams.viewportSize, aParams.size, aParams.flags);
+
+ RefPtr<gfxDrawable> svgDrawable = new gfxCallbackDrawable(cb, aParams.size);
+ return svgDrawable.forget();
+}
+
+std::tuple<RefPtr<SourceSurface>, IntSize> VectorImage::LookupCachedSurface(
+ const IntSize& aSize, const SVGImageContext& aSVGContext, uint32_t aFlags) {
+ // We can't use cached surfaces if we:
+ // - Explicitly disallow it via FLAG_BYPASS_SURFACE_CACHE
+ // - Want a blob recording which aren't supported by the cache.
+ // - Have animations which aren't supported by the cache.
+ if (aFlags & (FLAG_BYPASS_SURFACE_CACHE | FLAG_RECORD_BLOB) ||
+ mHaveAnimations) {
+ return std::make_tuple(RefPtr<SourceSurface>(), aSize);
+ }
+
+ LookupResult result(MatchType::NOT_FOUND);
+ SurfaceKey surfaceKey = VectorSurfaceKey(aSize, aSVGContext);
+ if ((aFlags & FLAG_SYNC_DECODE) || !(aFlags & FLAG_HIGH_QUALITY_SCALING)) {
+ result = SurfaceCache::Lookup(ImageKey(this), surfaceKey,
+ /* aMarkUsed = */ true);
+ } else {
+ result = SurfaceCache::LookupBestMatch(ImageKey(this), surfaceKey,
+ /* aMarkUsed = */ true);
+ }
+
+ IntSize rasterSize =
+ result.SuggestedSize().IsEmpty() ? aSize : result.SuggestedSize();
+ MOZ_ASSERT(result.Type() != MatchType::SUBSTITUTE_BECAUSE_PENDING);
+ if (!result || result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND) {
+ // No matching surface, or the OS freed the volatile buffer.
+ return std::make_tuple(RefPtr<SourceSurface>(), rasterSize);
+ }
+
+ RefPtr<SourceSurface> sourceSurface = result.Surface()->GetSourceSurface();
+ if (!sourceSurface) {
+ // Something went wrong. (Probably a GPU driver crash or device reset.)
+ // Attempt to recover.
+ RecoverFromLossOfSurfaces();
+ return std::make_tuple(RefPtr<SourceSurface>(), rasterSize);
+ }
+
+ return std::make_tuple(std::move(sourceSurface), rasterSize);
+}
+
+already_AddRefed<SourceSurface> VectorImage::CreateSurface(
+ const SVGDrawingParameters& aParams, gfxDrawable* aSVGDrawable,
+ bool& aWillCache) {
+ MOZ_ASSERT(mSVGDocumentWrapper->IsDrawing());
+ MOZ_ASSERT(!(aParams.flags & FLAG_RECORD_BLOB));
+
+ mSVGDocumentWrapper->UpdateViewportBounds(aParams.viewportSize);
+ mSVGDocumentWrapper->FlushImageTransformInvalidation();
+
+ // Determine whether or not we should put the surface to be created into
+ // the cache. If we fail, we need to reset this to false to let the caller
+ // know nothing was put in the cache.
+ aWillCache = !(aParams.flags & FLAG_BYPASS_SURFACE_CACHE) &&
+ // Refuse to cache animated images:
+ // XXX(seth): We may remove this restriction in bug 922893.
+ !mHaveAnimations &&
+ // The image is too big to fit in the cache:
+ SurfaceCache::CanHold(aParams.size);
+
+ // If we weren't given a context, then we know we just want the rasterized
+ // surface. We will create the frame below but only insert it into the cache
+ // if we actually need to.
+ if (!aWillCache && aParams.context) {
+ return nullptr;
+ }
+
+ // We're about to rerasterize, which may mean that some of the previous
+ // surfaces we've rasterized aren't useful anymore. We can allow them to
+ // expire from the cache by unlocking them here, and then sending out an
+ // invalidation. If this image is locked, any surfaces that are still useful
+ // will become locked again when Draw touches them, and the remainder will
+ // eventually expire.
+ if (aWillCache) {
+ SurfaceCache::UnlockEntries(ImageKey(this));
+ }
+
+ // If there is no context, the default backend is fine.
+ BackendType backend =
+ aParams.context ? aParams.context->GetDrawTarget()->GetBackendType()
+ : gfxPlatform::GetPlatform()->GetDefaultContentBackend();
+
+ if (backend == BackendType::DIRECT2D1_1) {
+ // We don't want to draw arbitrary content with D2D anymore
+ // because it doesn't support PushLayerWithBlend so switch to skia
+ backend = BackendType::SKIA;
+ }
+
+ // Try to create an imgFrame, initializing the surface it contains by drawing
+ // our gfxDrawable into it. (We use FILTER_NEAREST since we never scale here.)
+ auto frame = MakeNotNull<RefPtr<imgFrame>>();
+ nsresult rv = frame->InitWithDrawable(
+ aSVGDrawable, aParams.size, SurfaceFormat::OS_RGBA, SamplingFilter::POINT,
+ aParams.flags, backend);
+
+ // If we couldn't create the frame, it was probably because it would end
+ // up way too big. Generally it also wouldn't fit in the cache, but the prefs
+ // could be set such that the cache isn't the limiting factor.
+ if (NS_FAILED(rv)) {
+ aWillCache = false;
+ return nullptr;
+ }
+
+ // Take a strong reference to the frame's surface and make sure it hasn't
+ // already been purged by the operating system.
+ RefPtr<SourceSurface> surface = frame->GetSourceSurface();
+ if (!surface) {
+ aWillCache = false;
+ return nullptr;
+ }
+
+ // We created the frame, but only because we had no context to draw to
+ // directly. All the caller wants is the surface in this case.
+ if (!aWillCache) {
+ return surface.forget();
+ }
+
+ // Attempt to cache the frame.
+ SurfaceKey surfaceKey = VectorSurfaceKey(aParams.size, aParams.svgContext);
+ NotNull<RefPtr<ISurfaceProvider>> provider =
+ MakeNotNull<SimpleSurfaceProvider*>(ImageKey(this), surfaceKey, frame);
+
+ if (SurfaceCache::Insert(provider) == InsertOutcome::SUCCESS) {
+ if (aParams.size != aParams.drawSize) {
+ // We created a new surface that wasn't the size we requested, which means
+ // we entered factor-of-2 mode. We should purge any surfaces we no longer
+ // need rather than waiting for the cache to expire them.
+ SurfaceCache::PruneImage(ImageKey(this));
+ }
+ } else {
+ aWillCache = false;
+ }
+
+ return surface.forget();
+}
+
+void VectorImage::SendFrameComplete(bool aDidCache, uint32_t aFlags) {
+ // If the cache was not updated, we have nothing to do.
+ if (!aDidCache) {
+ return;
+ }
+
+ // Send out an invalidation so that surfaces that are still in use get
+ // re-locked. See the discussion of the UnlockSurfaces call above.
+ if (!(aFlags & FLAG_ASYNC_NOTIFY)) {
+ mProgressTracker->SyncNotifyProgress(FLAG_FRAME_COMPLETE,
+ GetMaxSizedIntRect());
+ } else {
+ NotNull<RefPtr<VectorImage>> image = WrapNotNull(this);
+ NS_DispatchToMainThread(CreateRenderBlockingRunnable(NS_NewRunnableFunction(
+ "ProgressTracker::SyncNotifyProgress", [=]() -> void {
+ RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
+ if (tracker) {
+ tracker->SyncNotifyProgress(FLAG_FRAME_COMPLETE,
+ GetMaxSizedIntRect());
+ }
+ })));
+ }
+}
+
+void VectorImage::Show(gfxDrawable* aDrawable,
+ const SVGDrawingParameters& aParams) {
+ // The surface size may differ from the size at which we wish to draw. As
+ // such, we may need to adjust the context/region to take this into account.
+ gfxContextMatrixAutoSaveRestore saveMatrix(aParams.context);
+ ImageRegion region(aParams.region);
+ if (aParams.drawSize != aParams.size) {
+ gfx::MatrixScales scale(
+ double(aParams.drawSize.width) / aParams.size.width,
+ double(aParams.drawSize.height) / aParams.size.height);
+ aParams.context->Multiply(gfx::Matrix::Scaling(scale));
+ region.Scale(1.0 / scale.xScale, 1.0 / scale.yScale);
+ }
+
+ MOZ_ASSERT(aDrawable, "Should have a gfxDrawable by now");
+ gfxUtils::DrawPixelSnapped(aParams.context, aDrawable,
+ SizeDouble(aParams.size), region,
+ SurfaceFormat::OS_RGBA, aParams.samplingFilter,
+ aParams.flags, aParams.opacity, false);
+
+ AutoProfilerImagePaintMarker PROFILER_RAII(this);
+#ifdef DEBUG
+ NotifyDrawingObservers();
+#endif
+
+ MOZ_ASSERT(mRenderingObserver, "Should have a rendering observer by now");
+ mRenderingObserver->ResumeHonoringInvalidations();
+}
+
+void VectorImage::RecoverFromLossOfSurfaces() {
+ NS_WARNING("An imgFrame became invalid. Attempting to recover...");
+
+ // Discard all existing frames, since they're probably all now invalid.
+ SurfaceCache::RemoveImage(ImageKey(this));
+}
+
+NS_IMETHODIMP
+VectorImage::StartDecoding(uint32_t aFlags, uint32_t aWhichFrame) {
+ // Nothing to do for SVG images
+ return NS_OK;
+}
+
+bool VectorImage::StartDecodingWithResult(uint32_t aFlags,
+ uint32_t aWhichFrame) {
+ // SVG images are ready to draw when they are loaded
+ return mIsFullyLoaded;
+}
+
+bool VectorImage::HasDecodedPixels() {
+ MOZ_ASSERT_UNREACHABLE("calling VectorImage::HasDecodedPixels");
+ return mIsFullyLoaded;
+}
+
+imgIContainer::DecodeResult VectorImage::RequestDecodeWithResult(
+ uint32_t aFlags, uint32_t aWhichFrame) {
+ // SVG images are ready to draw when they are loaded and don't have an error.
+
+ if (mError) {
+ return imgIContainer::DECODE_REQUEST_FAILED;
+ }
+
+ if (!mIsFullyLoaded) {
+ return imgIContainer::DECODE_REQUESTED;
+ }
+
+ return imgIContainer::DECODE_SURFACE_AVAILABLE;
+}
+
+NS_IMETHODIMP
+VectorImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags,
+ uint32_t aWhichFrame) {
+ // Nothing to do for SVG images, though in theory we could rasterize to the
+ // provided size ahead of time if we supported off-main-thread SVG
+ // rasterization...
+ return NS_OK;
+}
+
+//******************************************************************************
+
+NS_IMETHODIMP
+VectorImage::LockImage() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ mLockCount++;
+
+ if (mLockCount == 1) {
+ // Lock this image's surfaces in the SurfaceCache.
+ SurfaceCache::LockImage(ImageKey(this));
+ }
+
+ return NS_OK;
+}
+
+//******************************************************************************
+
+NS_IMETHODIMP
+VectorImage::UnlockImage() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (mLockCount == 0) {
+ MOZ_ASSERT_UNREACHABLE("Calling UnlockImage with a zero lock count");
+ return NS_ERROR_ABORT;
+ }
+
+ mLockCount--;
+
+ if (mLockCount == 0) {
+ // Unlock this image's surfaces in the SurfaceCache.
+ SurfaceCache::UnlockImage(ImageKey(this));
+ }
+
+ return NS_OK;
+}
+
+//******************************************************************************
+
+NS_IMETHODIMP
+VectorImage::RequestDiscard() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (mDiscardable && mLockCount == 0) {
+ SurfaceCache::RemoveImage(ImageKey(this));
+ mProgressTracker->OnDiscard();
+ }
+
+ return NS_OK;
+}
+
+void VectorImage::OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) {
+ MOZ_ASSERT(mProgressTracker);
+
+ NS_DispatchToMainThread(NewRunnableMethod("ProgressTracker::OnDiscard",
+ mProgressTracker,
+ &ProgressTracker::OnDiscard));
+}
+
+//******************************************************************************
+NS_IMETHODIMP
+VectorImage::ResetAnimation() {
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (!mIsFullyLoaded || !mHaveAnimations) {
+ return NS_OK; // There are no animations to be reset.
+ }
+
+ mSVGDocumentWrapper->ResetAnimation();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP_(float)
+VectorImage::GetFrameIndex(uint32_t aWhichFrame) {
+ MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE, "Invalid argument");
+ return aWhichFrame == FRAME_FIRST
+ ? 0.0f
+ : mSVGDocumentWrapper->GetCurrentTimeAsFloat();
+}
+
+//------------------------------------------------------------------------------
+// nsIRequestObserver methods
+
+//******************************************************************************
+NS_IMETHODIMP
+VectorImage::OnStartRequest(nsIRequest* aRequest) {
+ MOZ_ASSERT(!mSVGDocumentWrapper,
+ "Repeated call to OnStartRequest -- can this happen?");
+
+ mSVGDocumentWrapper = new SVGDocumentWrapper();
+ nsresult rv = mSVGDocumentWrapper->OnStartRequest(aRequest);
+ if (NS_FAILED(rv)) {
+ mSVGDocumentWrapper = nullptr;
+ mError = true;
+ return rv;
+ }
+
+ // Create a listener to wait until the SVG document is fully loaded, which
+ // will signal that this image is ready to render. Certain error conditions
+ // will prevent us from ever getting this notification, so we also create a
+ // listener that waits for parsing to complete and cancels the
+ // SVGLoadEventListener if needed. The listeners are automatically attached
+ // to the document by their constructors.
+ SVGDocument* document = mSVGDocumentWrapper->GetDocument();
+ mLoadEventListener = new SVGLoadEventListener(document, this);
+ mParseCompleteListener = new SVGParseCompleteListener(document, this);
+
+ // Displayed documents will call InitUseCounters under SetScriptGlobalObject,
+ // but SVG image documents never get a script global object, so we initialize
+ // use counters here, right after the document has been created.
+ document->InitUseCounters();
+
+ return NS_OK;
+}
+
+//******************************************************************************
+NS_IMETHODIMP
+VectorImage::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mSVGDocumentWrapper->OnStopRequest(aRequest, aStatus);
+}
+
+void VectorImage::OnSVGDocumentParsed() {
+ MOZ_ASSERT(mParseCompleteListener, "Should have the parse complete listener");
+ MOZ_ASSERT(mLoadEventListener, "Should have the load event listener");
+
+ if (!mSVGDocumentWrapper->GetRootSVGElem()) {
+ // This is an invalid SVG document. It may have failed to parse, or it may
+ // be missing the <svg> root element, or the <svg> root element may not
+ // declare the correct namespace. In any of these cases, we'll never be
+ // notified that the SVG finished loading, so we need to treat this as an
+ // error.
+ OnSVGDocumentError();
+ }
+}
+
+void VectorImage::CancelAllListeners() {
+ if (mParseCompleteListener) {
+ mParseCompleteListener->Cancel();
+ mParseCompleteListener = nullptr;
+ }
+ if (mLoadEventListener) {
+ mLoadEventListener->Cancel();
+ mLoadEventListener = nullptr;
+ }
+}
+
+void VectorImage::OnSVGDocumentLoaded() {
+ MOZ_ASSERT(mSVGDocumentWrapper->GetRootSVGElem(),
+ "Should have parsed successfully");
+ MOZ_ASSERT(!mIsFullyLoaded && !mHaveAnimations,
+ "These flags shouldn't get set until OnSVGDocumentLoaded. "
+ "Duplicate calls to OnSVGDocumentLoaded?");
+
+ CancelAllListeners();
+
+ // XXX Flushing is wasteful if embedding frame hasn't had initial reflow.
+ mSVGDocumentWrapper->FlushLayout();
+
+ // This is the earliest point that we can get accurate use counter data
+ // for a valid SVG document. Without the FlushLayout call, we would miss
+ // any CSS property usage that comes from SVG presentation attributes.
+ mSVGDocumentWrapper->GetDocument()->ReportDocumentUseCounters();
+
+ mIsFullyLoaded = true;
+ mHaveAnimations = mSVGDocumentWrapper->IsAnimated();
+
+ // Start listening to our image for rendering updates.
+ mRenderingObserver = new SVGRootRenderingObserver(mSVGDocumentWrapper, this);
+
+ // ProgressTracker::SyncNotifyProgress may release us, so ensure we
+ // stick around long enough to complete our work.
+ RefPtr<VectorImage> kungFuDeathGrip(this);
+
+ // Tell *our* observers that we're done loading.
+ if (mProgressTracker) {
+ Progress progress = FLAG_SIZE_AVAILABLE | FLAG_HAS_TRANSPARENCY |
+ FLAG_FRAME_COMPLETE | FLAG_DECODE_COMPLETE;
+
+ if (mHaveAnimations) {
+ progress |= FLAG_IS_ANIMATED;
+ }
+
+ // Merge in any saved progress from OnImageDataComplete.
+ if (mLoadProgress) {
+ progress |= *mLoadProgress;
+ mLoadProgress = Nothing();
+ }
+
+ mProgressTracker->SyncNotifyProgress(progress, GetMaxSizedIntRect());
+ }
+
+ EvaluateAnimation();
+}
+
+void VectorImage::OnSVGDocumentError() {
+ CancelAllListeners();
+
+ mError = true;
+
+ // We won't enter OnSVGDocumentLoaded, so report use counters now for this
+ // invalid document.
+ ReportDocumentUseCounters();
+
+ if (mProgressTracker) {
+ // Notify observers about the error and unblock page load.
+ Progress progress = FLAG_HAS_ERROR;
+
+ // Merge in any saved progress from OnImageDataComplete.
+ if (mLoadProgress) {
+ progress |= *mLoadProgress;
+ mLoadProgress = Nothing();
+ }
+
+ mProgressTracker->SyncNotifyProgress(progress);
+ }
+}
+
+//------------------------------------------------------------------------------
+// nsIStreamListener method
+
+//******************************************************************************
+NS_IMETHODIMP
+VectorImage::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInStr,
+ uint64_t aSourceOffset, uint32_t aCount) {
+ if (mError) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mSVGDocumentWrapper->OnDataAvailable(aRequest, aInStr, aSourceOffset,
+ aCount);
+}
+
+// --------------------------
+// Invalidation helper method
+
+void VectorImage::InvalidateObserversOnNextRefreshDriverTick() {
+ if (mHasPendingInvalidation) {
+ return;
+ }
+
+ mHasPendingInvalidation = true;
+
+ // Animated images can wait for the refresh tick.
+ if (mHaveAnimations) {
+ return;
+ }
+
+ // Non-animated images won't get the refresh tick, so we should just send an
+ // invalidation outside the current execution context. We need to defer
+ // because the layout tree is in the middle of invalidation, and the tree
+ // state needs to be consistent. Specifically only some of the frames have
+ // had the NS_FRAME_DESCENDANT_NEEDS_PAINT and/or NS_FRAME_NEEDS_PAINT bits
+ // set by InvalidateFrameInternal in layout/generic/nsFrame.cpp. These bits
+ // get cleared when we repaint the SVG into a surface by
+ // nsIFrame::ClearInvalidationStateBits in nsDisplayList::PaintRoot.
+ nsCOMPtr<nsIEventTarget> eventTarget;
+ if (mProgressTracker) {
+ eventTarget = mProgressTracker->GetEventTarget();
+ } else {
+ eventTarget = do_GetMainThread();
+ }
+
+ RefPtr<VectorImage> self(this);
+ nsCOMPtr<nsIRunnable> ev(NS_NewRunnableFunction(
+ "VectorImage::SendInvalidationNotifications",
+ [=]() -> void { self->SendInvalidationNotifications(); }));
+ eventTarget->Dispatch(CreateRenderBlockingRunnable(ev.forget()),
+ NS_DISPATCH_NORMAL);
+}
+
+void VectorImage::PropagateUseCounters(Document* aReferencingDocument) {
+ if (Document* doc = mSVGDocumentWrapper->GetDocument()) {
+ doc->PropagateImageUseCounters(aReferencingDocument);
+ }
+}
+
+nsIntSize VectorImage::OptimalImageSizeForDest(const gfxSize& aDest,
+ uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ uint32_t aFlags) {
+ MOZ_ASSERT(aDest.width >= 0 || ceil(aDest.width) <= INT32_MAX ||
+ aDest.height >= 0 || ceil(aDest.height) <= INT32_MAX,
+ "Unexpected destination size");
+
+ // We can rescale SVGs freely, so just return the provided destination size.
+ return nsIntSize::Ceil(aDest.width, aDest.height);
+}
+
+already_AddRefed<imgIContainer> VectorImage::Unwrap() {
+ nsCOMPtr<imgIContainer> self(this);
+ return self.forget();
+}
+
+void VectorImage::MediaFeatureValuesChangedAllDocuments(
+ const MediaFeatureChange& aChange) {
+ if (!mSVGDocumentWrapper) {
+ return;
+ }
+
+ // Don't bother if the document hasn't loaded yet.
+ if (!mIsFullyLoaded) {
+ return;
+ }
+
+ if (Document* doc = mSVGDocumentWrapper->GetDocument()) {
+ if (RefPtr<nsPresContext> presContext = doc->GetPresContext()) {
+ presContext->MediaFeatureValuesChanged(
+ aChange, MediaFeatureChangePropagation::All);
+ // Media feature value changes don't happen in the middle of layout,
+ // so we don't need to call InvalidateObserversOnNextRefreshDriverTick
+ // to invalidate asynchronously.
+ if (presContext->FlushPendingMediaFeatureValuesChanged()) {
+ // NOTE(emilio): SendInvalidationNotifications flushes layout via
+ // VectorImage::CreateSurface -> FlushImageTransformInvalidation.
+ SendInvalidationNotifications();
+ }
+ }
+ }
+}
+
+nsresult VectorImage::GetHotspotX(int32_t* aX) {
+ return Image::GetHotspotX(aX);
+}
+
+nsresult VectorImage::GetHotspotY(int32_t* aY) {
+ return Image::GetHotspotY(aY);
+}
+
+void VectorImage::ReportDocumentUseCounters() {
+ if (!mSVGDocumentWrapper) {
+ return;
+ }
+
+ if (Document* doc = mSVGDocumentWrapper->GetDocument()) {
+ doc->ReportDocumentUseCounters();
+ }
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/VectorImage.h b/image/VectorImage.h
new file mode 100644
index 0000000000..fc7df04483
--- /dev/null
+++ b/image/VectorImage.h
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_VectorImage_h
+#define mozilla_image_VectorImage_h
+
+#include "Image.h"
+#include "nsIStreamListener.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/MemoryReporting.h"
+
+class nsIRequest;
+class gfxDrawable;
+
+namespace mozilla {
+struct MediaFeatureChange;
+
+namespace image {
+
+class SourceSurfaceBlobImage;
+struct SVGDrawingParameters;
+class SVGDocumentWrapper;
+class SVGRootRenderingObserver;
+class SVGLoadEventListener;
+class SVGParseCompleteListener;
+
+class VectorImage final : public ImageResource, public nsIStreamListener {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSISTREAMLISTENER
+ NS_DECL_IMGICONTAINER
+
+ // (no public constructor - use ImageFactory)
+
+ // Methods inherited from Image
+ virtual size_t SizeOfSourceWithComputedFallback(
+ SizeOfState& aState) const override;
+
+ virtual nsresult OnImageDataAvailable(nsIRequest* aRequest,
+ nsIInputStream* aInStr,
+ uint64_t aSourceOffset,
+ uint32_t aCount) override;
+ virtual nsresult OnImageDataComplete(nsIRequest* aRequest, nsresult aResult,
+ bool aLastPart) override;
+
+ virtual void OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) override;
+
+ /**
+ * Callback for SVGRootRenderingObserver.
+ *
+ * This just sets a dirty flag that we check in VectorImage::RequestRefresh,
+ * which is called under the ticks of the refresh driver of any observing
+ * documents that we may have. Only then (after all animations in this image
+ * have been updated) do we send out "frame changed" notifications,
+ */
+ void InvalidateObserversOnNextRefreshDriverTick();
+
+ // Callback for SVGParseCompleteListener.
+ void OnSVGDocumentParsed();
+
+ // Callbacks for SVGLoadEventListener.
+ void OnSVGDocumentLoaded();
+ void OnSVGDocumentError();
+
+ protected:
+ explicit VectorImage(nsIURI* aURI = nullptr);
+ virtual ~VectorImage();
+
+ virtual nsresult StartAnimation() override;
+ virtual nsresult StopAnimation() override;
+ virtual bool ShouldAnimate() override;
+
+ private:
+ friend class SourceSurfaceBlobImage;
+
+ /**
+ * Attempt to find a matching cached surface in the SurfaceCache. Returns the
+ * cached surface, if found, and the size to rasterize at, if applicable.
+ * If we cannot rasterize, it will be the requested size to draw at (aSize).
+ */
+ std::tuple<RefPtr<gfx::SourceSurface>, gfx::IntSize> LookupCachedSurface(
+ const gfx::IntSize& aSize, const SVGImageContext& aSVGContext,
+ uint32_t aFlags);
+
+ bool MaybeRestrictSVGContext(SVGImageContext& aSVGContext, uint32_t aFlags);
+
+ /// Create a gfxDrawable which callbacks into the SVG document.
+ already_AddRefed<gfxDrawable> CreateSVGDrawable(
+ const SVGDrawingParameters& aParams);
+
+ /// Rasterize the SVG into a surface. aWillCache will be set to whether or
+ /// not the new surface was put into the cache.
+ already_AddRefed<gfx::SourceSurface> CreateSurface(
+ const SVGDrawingParameters& aParams, gfxDrawable* aSVGDrawable,
+ bool& aWillCache);
+
+ /// Send a frame complete notification if appropriate. Must be called only
+ /// after all drawing has been completed.
+ void SendFrameComplete(bool aDidCache, uint32_t aFlags);
+
+ void Show(gfxDrawable* aDrawable, const SVGDrawingParameters& aParams);
+
+ nsresult Init(const char* aMimeType, uint32_t aFlags);
+
+ /**
+ * In catastrophic circumstances like a GPU driver crash, we may lose our
+ * surfaces even if they're locked. RecoverFromLossOfSurfaces discards all
+ * existing surfaces, allowing us to recover.
+ */
+ void RecoverFromLossOfSurfaces();
+
+ void CancelAllListeners();
+ void SendInvalidationNotifications();
+
+ void ReportDocumentUseCounters();
+
+ RefPtr<SVGDocumentWrapper> mSVGDocumentWrapper;
+ RefPtr<SVGRootRenderingObserver> mRenderingObserver;
+ RefPtr<SVGLoadEventListener> mLoadEventListener;
+ RefPtr<SVGParseCompleteListener> mParseCompleteListener;
+
+ /// Count of locks on this image (roughly correlated to visible instances).
+ uint32_t mLockCount;
+
+ // Stored result from the Necko load of the image, which we save in
+ // OnImageDataComplete if the underlying SVG document isn't loaded. If we save
+ // this, we actually notify this progress (and clear this value) in
+ // OnSVGDocumentLoaded or OnSVGDocumentError.
+ Maybe<Progress> mLoadProgress;
+
+ bool mIsInitialized; // Have we been initialized?
+ bool mDiscardable; // Are we discardable?
+ bool mIsFullyLoaded; // Has the SVG document finished
+ // loading?
+ bool mHaveAnimations; // Is our SVG content SMIL-animated?
+ // (Only set after mIsFullyLoaded.)
+ bool mHasPendingInvalidation; // Invalidate observers next refresh
+ // driver tick.
+
+ friend class ImageFactory;
+};
+
+inline NS_IMETHODIMP VectorImage::GetAnimationMode(uint16_t* aAnimationMode) {
+ return GetAnimationModeInternal(aAnimationMode);
+}
+
+inline NS_IMETHODIMP VectorImage::SetAnimationMode(uint16_t aAnimationMode) {
+ return SetAnimationModeInternal(aAnimationMode);
+}
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_VectorImage_h
diff --git a/image/WebRenderImageProvider.h b/image/WebRenderImageProvider.h
new file mode 100644
index 0000000000..84fee8cb47
--- /dev/null
+++ b/image/WebRenderImageProvider.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MOZILLA_IMAGE_WEBRENDERIMAGEPROVIDER_H_
+#define MOZILLA_IMAGE_WEBRENDERIMAGEPROVIDER_H_
+
+#include "nsISupportsImpl.h"
+
+namespace mozilla {
+namespace layers {
+class RenderRootStateManager;
+}
+
+namespace wr {
+class IpcResourceUpdateQueue;
+struct ExternalImageId;
+struct ImageKey;
+} // namespace wr
+
+namespace image {
+
+class ImageResource;
+using ImageProviderId = uint32_t;
+
+class WebRenderImageProvider {
+ public:
+ // Subclasses may or may not be XPCOM classes, so we just require that they
+ // implement AddRef and Release.
+ NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
+
+ ImageProviderId GetProviderId() const { return mProviderId; }
+
+ static ImageProviderId AllocateProviderId();
+
+ /**
+ * Generate an ImageKey for the given frame.
+ * @param aSurface The current frame. This should match what was cached via
+ * SetCurrentFrame, but if it does not, it will need to
+ * regenerate the cached ImageKey.
+ */
+ virtual nsresult UpdateKey(layers::RenderRootStateManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources,
+ wr::ImageKey& aKey) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ /**
+ * Invalidate if a blob recording, requiring it to be regenerated.
+ */
+ virtual void InvalidateRecording() {}
+
+ protected:
+ WebRenderImageProvider(const ImageResource* aImage);
+
+ private:
+ ImageProviderId mProviderId;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif /* MOZILLA_IMAGE_WEBRENDERIMAGEPROVIDER_H_ */
diff --git a/image/build/components.conf b/image/build/components.conf
new file mode 100644
index 0000000000..182d1cd1af
--- /dev/null
+++ b/image/build/components.conf
@@ -0,0 +1,85 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+Headers = [
+ '/image/build/nsImageModule.h',
+]
+
+InitFunc = 'mozilla::image::EnsureModuleInitialized'
+# This is called by LayoutModuleDtor to ensure it happens at the right time
+# during shutdown.
+# UnloadFunc = 'mozilla::image::ShutdownModule'
+
+Classes = [
+ # XXX We would like to get rid of the imgLoader factory constructor. See the
+ # comment documenting the imgLoader constructor.
+ {
+ 'cid': '{c1354898-e3fe-4602-88a7-c4520c21cb4e}',
+ 'contract_ids': [
+ '@mozilla.org/image/cache;1',
+ '@mozilla.org/image/loader;1',
+ ],
+ 'type': 'imgLoader',
+ 'headers': ['imgLoader.h'],
+ 'init_method': 'Init',
+ 'categories': {
+ 'content-sniffing-services': '@mozilla.org/image/loader;1',
+ 'orb-content-sniffers': '@mozilla.org/image/loader;1',
+ 'net-and-orb-content-sniffers': '@mozilla.org/image/loader;1',
+ },
+ },
+ {
+ 'cid': '{f6fcd651-164b-4416-b001-9c8c393fd93b}',
+ 'contract_ids': [
+ '@mozilla.org/image-blocker-content-policy;1',
+ ],
+ 'type': 'mozilla::image::ImageBlocker',
+ 'headers': ['ImageBlocker.h'],
+ 'categories': {'content-policy': '@mozilla.org/image-blocker-content-policy;1'},
+ },
+ {
+ 'cid': '{20557898-1dd2-11b2-8f65-9c462ee2bc95}',
+ 'contract_ids': ['@mozilla.org/image/request;1'],
+ 'type': 'imgRequestProxy',
+ 'headers': ['imgRequestProxy.h'],
+ },
+ {
+ 'cid': '{3d8fa16d-c9e1-4b50-bdef-2c7ae249967a}',
+ 'contract_ids': ['@mozilla.org/image/tools;1'],
+ 'type': 'mozilla::image::imgTools',
+ 'headers': ['/image/imgTools.h'],
+ },
+ {
+ 'cid': '{13a5320c-4c91-4fa4-bd16-b081a3ba8c0b}',
+ 'contract_ids': ['@mozilla.org/image/encoder;2?type=image/bmp'],
+ 'type': 'nsBMPEncoder',
+ 'headers': ['/image/encoders/bmp/nsBMPEncoder.h'],
+ },
+ {
+ 'cid': '{92ae3ab2-8968-41b1-8709-b6123bceaf21}',
+ 'contract_ids': ['@mozilla.org/image/encoder;2?type=image/vnd.microsoft.icon'],
+ 'type': 'nsICOEncoder',
+ 'headers': ['/image/encoders/ico/nsICOEncoder.h'],
+ },
+ {
+ 'cid': '{ac2bb8fe-eeeb-4572-b40f-be03932b56e0}',
+ 'contract_ids': ['@mozilla.org/image/encoder;2?type=image/jpeg'],
+ 'type': 'nsJPEGEncoder',
+ 'headers': ['/image/encoders/jpeg/nsJPEGEncoder.h'],
+ },
+ {
+ 'cid': '{38d1592e-b81e-432b-86f8-471878bbfe07}',
+ 'contract_ids': ['@mozilla.org/image/encoder;2?type=image/png'],
+ 'type': 'nsPNGEncoder',
+ 'headers': ['/image/encoders/png/nsPNGEncoder.h'],
+ },
+ {
+ 'cid': '{a8e5a8e5-bebf-4512-9f50-e41e4748ce28}',
+ 'contract_ids': ['@mozilla.org/image/encoder;2?type=image/webp'],
+ 'type': 'nsWebPEncoder',
+ 'headers': ['/image/encoders/webp/nsWebPEncoder.h'],
+ },
+]
diff --git a/image/build/moz.build b/image/build/moz.build
new file mode 100644
index 0000000000..7ba10e42b9
--- /dev/null
+++ b/image/build/moz.build
@@ -0,0 +1,26 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+EXPORTS += [
+ "nsImageModule.h",
+]
+
+SOURCES += [
+ "nsImageModule.cpp",
+]
+
+XPCOM_MANIFESTS += [
+ "components.conf",
+]
+
+FINAL_LIBRARY = "xul"
+LOCAL_INCLUDES += [
+ "/image",
+ "/image/encoders/bmp",
+ "/image/encoders/ico",
+ "/image/encoders/jpeg",
+ "/image/encoders/png",
+]
diff --git a/image/build/nsImageModule.cpp b/image/build/nsImageModule.cpp
new file mode 100644
index 0000000000..28fb8bb330
--- /dev/null
+++ b/image/build/nsImageModule.cpp
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsImageModule.h"
+
+#include "mozilla/ModuleUtils.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/StaticPrefs_image.h"
+
+#include "DecodePool.h"
+#include "ImageFactory.h"
+#include "nsICategoryManager.h"
+#include "nsServiceManagerUtils.h"
+#include "ShutdownTracker.h"
+#include "SurfaceCache.h"
+#include "imgLoader.h"
+
+using namespace mozilla::image;
+
+struct ImageEnablementCookie {
+ bool (*mIsEnabled)();
+ const nsLiteralCString mMimeType;
+};
+
+static void UpdateContentViewerRegistration(const char* aPref, void* aData) {
+ auto* cookie = static_cast<ImageEnablementCookie*>(aData);
+
+ nsCOMPtr<nsICategoryManager> catMan =
+ do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
+ if (!catMan) {
+ return;
+ }
+
+ static nsLiteralCString kCategory = "Gecko-Content-Viewers"_ns;
+ static nsLiteralCString kContractId =
+ "@mozilla.org/content/plugin/document-loader-factory;1"_ns;
+
+ if (cookie->mIsEnabled()) {
+ catMan->AddCategoryEntry(kCategory, cookie->mMimeType, kContractId,
+ false /* aPersist */, true /* aReplace */);
+ } else {
+ catMan->DeleteCategoryEntry(
+ kCategory, cookie->mMimeType, false /* aPersist */
+ );
+ }
+}
+
+static bool sInitialized = false;
+nsresult mozilla::image::EnsureModuleInitialized() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (sInitialized) {
+ return NS_OK;
+ }
+
+ static ImageEnablementCookie kAVIFCookie = {
+ mozilla::StaticPrefs::image_avif_enabled, "image/avif"_ns};
+ static ImageEnablementCookie kJXLCookie = {
+ mozilla::StaticPrefs::image_jxl_enabled, "image/jxl"_ns};
+ static ImageEnablementCookie kWebPCookie = {
+ mozilla::StaticPrefs::image_webp_enabled, "image/webp"_ns};
+ Preferences::RegisterCallbackAndCall(UpdateContentViewerRegistration,
+ "image.avif.enabled", &kAVIFCookie);
+ Preferences::RegisterCallbackAndCall(UpdateContentViewerRegistration,
+ "image.jxl.enabled", &kJXLCookie);
+ Preferences::RegisterCallbackAndCall(UpdateContentViewerRegistration,
+ "image.webp.enabled", &kWebPCookie);
+
+ mozilla::image::ShutdownTracker::Initialize();
+ mozilla::image::ImageFactory::Initialize();
+ mozilla::image::DecodePool::Initialize();
+ mozilla::image::SurfaceCache::Initialize();
+ imgLoader::GlobalInit();
+ sInitialized = true;
+ return NS_OK;
+}
+
+void mozilla::image::ShutdownModule() {
+ if (!sInitialized) {
+ return;
+ }
+ imgLoader::Shutdown();
+ mozilla::image::SurfaceCache::Shutdown();
+ sInitialized = false;
+}
diff --git a/image/build/nsImageModule.h b/image/build/nsImageModule.h
new file mode 100644
index 0000000000..130e59b868
--- /dev/null
+++ b/image/build/nsImageModule.h
@@ -0,0 +1,20 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_build_nsImageModule_h
+#define mozilla_image_build_nsImageModule_h
+
+#include "nsError.h"
+
+namespace mozilla {
+namespace image {
+
+nsresult EnsureModuleInitialized();
+void ShutdownModule();
+
+} /* namespace image */
+} /* namespace mozilla */
+
+#endif // mozilla_image_build_nsImageModule_h
diff --git a/image/decoders/EXIF.cpp b/image/decoders/EXIF.cpp
new file mode 100644
index 0000000000..97563248c7
--- /dev/null
+++ b/image/decoders/EXIF.cpp
@@ -0,0 +1,519 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "EXIF.h"
+
+#include "mozilla/EndianUtils.h"
+#include "mozilla/StaticPrefs_image.h"
+
+namespace mozilla::image {
+
+// Section references in this file refer to the EXIF v2.3 standard, also known
+// as CIPA DC-008-Translation-2010.
+
+// See Section 4.6.4, Table 4.
+// Typesafe enums are intentionally not used here since we're comparing to raw
+// integers produced by parsing.
+enum class EXIFTag : uint16_t {
+ Orientation = 0x112,
+ XResolution = 0x11a,
+ YResolution = 0x11b,
+ PixelXDimension = 0xa002,
+ PixelYDimension = 0xa003,
+ ResolutionUnit = 0x128,
+ IFDPointer = 0x8769,
+};
+
+// See Section 4.6.2.
+enum EXIFType {
+ ByteType = 1,
+ ASCIIType = 2,
+ ShortType = 3,
+ LongType = 4,
+ RationalType = 5,
+ UndefinedType = 7,
+ SignedLongType = 9,
+ SignedRational = 10,
+};
+
+static const char* EXIFHeader = "Exif\0\0";
+static const uint32_t EXIFHeaderLength = 6;
+static const uint32_t TIFFHeaderStart = EXIFHeaderLength;
+
+struct ParsedEXIFData {
+ Orientation orientation;
+ Maybe<float> resolutionX;
+ Maybe<float> resolutionY;
+ Maybe<uint32_t> pixelXDimension;
+ Maybe<uint32_t> pixelYDimension;
+ Maybe<ResolutionUnit> resolutionUnit;
+};
+
+static float ToDppx(float aResolution, ResolutionUnit aUnit) {
+ constexpr float kPointsPerInch = 72.0f;
+ constexpr float kPointsPerCm = 1.0f / 2.54f;
+ switch (aUnit) {
+ case ResolutionUnit::Dpi:
+ return aResolution / kPointsPerInch;
+ case ResolutionUnit::Dpcm:
+ return aResolution / kPointsPerCm;
+ }
+ MOZ_CRASH("Unknown resolution unit?");
+}
+
+static Resolution ResolutionFromParsedData(const ParsedEXIFData& aData,
+ const gfx::IntSize& aRealImageSize) {
+ if (!aData.resolutionUnit || !aData.resolutionX || !aData.resolutionY) {
+ return {};
+ }
+
+ Resolution resolution{ToDppx(*aData.resolutionX, *aData.resolutionUnit),
+ ToDppx(*aData.resolutionY, *aData.resolutionUnit)};
+
+ if (StaticPrefs::image_exif_density_correction_sanity_check_enabled()) {
+ if (!aData.pixelXDimension || !aData.pixelYDimension) {
+ return {};
+ }
+
+ const gfx::IntSize exifSize(*aData.pixelXDimension, *aData.pixelYDimension);
+
+ gfx::IntSize scaledSize = aRealImageSize;
+ resolution.ApplyTo(scaledSize.width, scaledSize.height);
+
+ if (exifSize != scaledSize) {
+ return {};
+ }
+ }
+
+ return resolution;
+}
+
+/////////////////////////////////////////////////////////////
+// Parse EXIF data, typically found in a JPEG's APP1 segment.
+/////////////////////////////////////////////////////////////
+EXIFData EXIFParser::ParseEXIF(const uint8_t* aData, const uint32_t aLength,
+ const gfx::IntSize& aRealImageSize) {
+ if (!Initialize(aData, aLength)) {
+ return EXIFData();
+ }
+
+ if (!ParseEXIFHeader()) {
+ return EXIFData();
+ }
+
+ uint32_t offsetIFD;
+ if (!ParseTIFFHeader(offsetIFD)) {
+ return EXIFData();
+ }
+
+ JumpTo(offsetIFD);
+
+ ParsedEXIFData data;
+ ParseIFD(data);
+
+ return EXIFData{data.orientation,
+ ResolutionFromParsedData(data, aRealImageSize)};
+}
+
+/////////////////////////////////////////////////////////
+// Parse the EXIF header. (Section 4.7.2, Figure 30)
+/////////////////////////////////////////////////////////
+bool EXIFParser::ParseEXIFHeader() {
+ return MatchString(EXIFHeader, EXIFHeaderLength);
+}
+
+/////////////////////////////////////////////////////////
+// Parse the TIFF header. (Section 4.5.2, Table 1)
+/////////////////////////////////////////////////////////
+bool EXIFParser::ParseTIFFHeader(uint32_t& aIFD0OffsetOut) {
+ // Determine byte order.
+ if (MatchString("MM\0*", 4)) {
+ mByteOrder = ByteOrder::BigEndian;
+ } else if (MatchString("II*\0", 4)) {
+ mByteOrder = ByteOrder::LittleEndian;
+ } else {
+ return false;
+ }
+
+ // Determine offset of the 0th IFD. (It shouldn't be greater than 64k, which
+ // is the maximum size of the entry APP1 segment.)
+ uint32_t ifd0Offset;
+ if (!ReadUInt32(ifd0Offset) || ifd0Offset > 64 * 1024) {
+ return false;
+ }
+
+ // The IFD offset is relative to the beginning of the TIFF header, which
+ // begins after the EXIF header, so we need to increase the offset
+ // appropriately.
+ aIFD0OffsetOut = ifd0Offset + TIFFHeaderStart;
+ return true;
+}
+
+// An arbitrary limit on the amount of pointers that we'll chase, to prevent bad
+// inputs getting us stuck.
+constexpr uint32_t kMaxEXIFDepth = 16;
+
+/////////////////////////////////////////////////////////
+// Parse the entries in IFD0. (Section 4.6.2)
+/////////////////////////////////////////////////////////
+void EXIFParser::ParseIFD(ParsedEXIFData& aData, uint32_t aDepth) {
+ if (NS_WARN_IF(aDepth > kMaxEXIFDepth)) {
+ return;
+ }
+
+ uint16_t entryCount;
+ if (!ReadUInt16(entryCount)) {
+ return;
+ }
+
+ for (uint16_t entry = 0; entry < entryCount; ++entry) {
+ // Read the fields of the 12-byte entry.
+ uint16_t tag;
+ if (!ReadUInt16(tag)) {
+ return;
+ }
+
+ uint16_t type;
+ if (!ReadUInt16(type)) {
+ return;
+ }
+
+ uint32_t count;
+ if (!ReadUInt32(count)) {
+ return;
+ }
+
+ switch (EXIFTag(tag)) {
+ case EXIFTag::Orientation:
+ // We should have an orientation value here; go ahead and parse it.
+ if (!ParseOrientation(type, count, aData.orientation)) {
+ return;
+ }
+ break;
+ case EXIFTag::ResolutionUnit:
+ if (!ParseResolutionUnit(type, count, aData.resolutionUnit)) {
+ return;
+ }
+ break;
+ case EXIFTag::XResolution:
+ if (!ParseResolution(type, count, aData.resolutionX)) {
+ return;
+ }
+ break;
+ case EXIFTag::YResolution:
+ if (!ParseResolution(type, count, aData.resolutionY)) {
+ return;
+ }
+ break;
+ case EXIFTag::PixelXDimension:
+ if (!ParseDimension(type, count, aData.pixelXDimension)) {
+ return;
+ }
+ break;
+ case EXIFTag::PixelYDimension:
+ if (!ParseDimension(type, count, aData.pixelYDimension)) {
+ return;
+ }
+ break;
+ case EXIFTag::IFDPointer: {
+ uint32_t offset;
+ if (!ReadUInt32(offset)) {
+ return;
+ }
+
+ ScopedJump jump(*this, offset + TIFFHeaderStart);
+ ParseIFD(aData, aDepth + 1);
+ break;
+ }
+
+ default:
+ Advance(4);
+ break;
+ }
+ }
+}
+
+bool EXIFParser::ReadRational(float& aOut) {
+ // Values larger than 4 bytes (like rationals) are specified as an offset into
+ // the TIFF header.
+ uint32_t valueOffset;
+ if (!ReadUInt32(valueOffset)) {
+ return false;
+ }
+ ScopedJump jumpToHeader(*this, valueOffset + TIFFHeaderStart);
+ uint32_t numerator;
+ if (!ReadUInt32(numerator)) {
+ return false;
+ }
+ uint32_t denominator;
+ if (!ReadUInt32(denominator)) {
+ return false;
+ }
+ if (denominator == 0) {
+ return false;
+ }
+ aOut = float(numerator) / float(denominator);
+ return true;
+}
+
+bool EXIFParser::ParseResolution(uint16_t aType, uint32_t aCount,
+ Maybe<float>& aOut) {
+ if (!StaticPrefs::image_exif_density_correction_enabled()) {
+ Advance(4);
+ return true;
+ }
+ if (aType != RationalType || aCount != 1) {
+ return false;
+ }
+ float value;
+ if (!ReadRational(value)) {
+ return false;
+ }
+ if (value == 0.0f) {
+ return false;
+ }
+ aOut = Some(value);
+ return true;
+}
+
+bool EXIFParser::ParseDimension(uint16_t aType, uint32_t aCount,
+ Maybe<uint32_t>& aOut) {
+ if (!StaticPrefs::image_exif_density_correction_enabled()) {
+ Advance(4);
+ return true;
+ }
+
+ if (aCount != 1) {
+ return false;
+ }
+
+ switch (aType) {
+ case ShortType: {
+ uint16_t value;
+ if (!ReadUInt16(value)) {
+ return false;
+ }
+ aOut = Some(value);
+ Advance(2);
+ break;
+ }
+ case LongType: {
+ uint32_t value;
+ if (!ReadUInt32(value)) {
+ return false;
+ }
+ aOut = Some(value);
+ break;
+ }
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool EXIFParser::ParseResolutionUnit(uint16_t aType, uint32_t aCount,
+ Maybe<ResolutionUnit>& aOut) {
+ if (!StaticPrefs::image_exif_density_correction_enabled()) {
+ Advance(4);
+ return true;
+ }
+ if (aType != ShortType || aCount != 1) {
+ return false;
+ }
+ uint16_t value;
+ if (!ReadUInt16(value)) {
+ return false;
+ }
+ switch (value) {
+ case 2:
+ aOut = Some(ResolutionUnit::Dpi);
+ break;
+ case 3:
+ aOut = Some(ResolutionUnit::Dpcm);
+ break;
+ default:
+ return false;
+ }
+
+ // This is a 32-bit field, but the unit value only occupies the first 16 bits.
+ // We need to advance another 16 bits to consume the entire field.
+ Advance(2);
+ return true;
+}
+
+bool EXIFParser::ParseOrientation(uint16_t aType, uint32_t aCount,
+ Orientation& aOut) {
+ // Sanity check the type and count.
+ if (aType != ShortType || aCount != 1) {
+ return false;
+ }
+
+ uint16_t value;
+ if (!ReadUInt16(value)) {
+ return false;
+ }
+
+ switch (value) {
+ case 1:
+ aOut = Orientation(Angle::D0, Flip::Unflipped);
+ break;
+ case 2:
+ aOut = Orientation(Angle::D0, Flip::Horizontal);
+ break;
+ case 3:
+ aOut = Orientation(Angle::D180, Flip::Unflipped);
+ break;
+ case 4:
+ aOut = Orientation(Angle::D180, Flip::Horizontal);
+ break;
+ case 5:
+ aOut = Orientation(Angle::D90, Flip::Horizontal);
+ break;
+ case 6:
+ aOut = Orientation(Angle::D90, Flip::Unflipped);
+ break;
+ case 7:
+ aOut = Orientation(Angle::D270, Flip::Horizontal);
+ break;
+ case 8:
+ aOut = Orientation(Angle::D270, Flip::Unflipped);
+ break;
+ default:
+ return false;
+ }
+
+ // This is a 32-bit field, but the orientation value only occupies the first
+ // 16 bits. We need to advance another 16 bits to consume the entire field.
+ Advance(2);
+ return true;
+}
+
+bool EXIFParser::Initialize(const uint8_t* aData, const uint32_t aLength) {
+ if (aData == nullptr) {
+ return false;
+ }
+
+ // An APP1 segment larger than 64k violates the JPEG standard.
+ if (aLength > 64 * 1024) {
+ return false;
+ }
+
+ mStart = mCurrent = aData;
+ mLength = mRemainingLength = aLength;
+ mByteOrder = ByteOrder::Unknown;
+ return true;
+}
+
+void EXIFParser::Advance(const uint32_t aDistance) {
+ if (mRemainingLength >= aDistance) {
+ mCurrent += aDistance;
+ mRemainingLength -= aDistance;
+ } else {
+ mCurrent = mStart;
+ mRemainingLength = 0;
+ }
+}
+
+void EXIFParser::JumpTo(const uint32_t aOffset) {
+ if (mLength >= aOffset) {
+ mCurrent = mStart + aOffset;
+ mRemainingLength = mLength - aOffset;
+ } else {
+ mCurrent = mStart;
+ mRemainingLength = 0;
+ }
+}
+
+bool EXIFParser::MatchString(const char* aString, const uint32_t aLength) {
+ if (mRemainingLength < aLength) {
+ return false;
+ }
+
+ for (uint32_t i = 0; i < aLength; ++i) {
+ if (mCurrent[i] != aString[i]) {
+ return false;
+ }
+ }
+
+ Advance(aLength);
+ return true;
+}
+
+bool EXIFParser::MatchUInt16(const uint16_t aValue) {
+ if (mRemainingLength < 2) {
+ return false;
+ }
+
+ bool matched;
+ switch (mByteOrder) {
+ case ByteOrder::LittleEndian:
+ matched = LittleEndian::readUint16(mCurrent) == aValue;
+ break;
+ case ByteOrder::BigEndian:
+ matched = BigEndian::readUint16(mCurrent) == aValue;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Should know the byte order by now");
+ matched = false;
+ }
+
+ if (matched) {
+ Advance(2);
+ }
+
+ return matched;
+}
+
+bool EXIFParser::ReadUInt16(uint16_t& aValue) {
+ if (mRemainingLength < 2) {
+ return false;
+ }
+
+ bool matched = true;
+ switch (mByteOrder) {
+ case ByteOrder::LittleEndian:
+ aValue = LittleEndian::readUint16(mCurrent);
+ break;
+ case ByteOrder::BigEndian:
+ aValue = BigEndian::readUint16(mCurrent);
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Should know the byte order by now");
+ matched = false;
+ }
+
+ if (matched) {
+ Advance(2);
+ }
+
+ return matched;
+}
+
+bool EXIFParser::ReadUInt32(uint32_t& aValue) {
+ if (mRemainingLength < 4) {
+ return false;
+ }
+
+ bool matched = true;
+ switch (mByteOrder) {
+ case ByteOrder::LittleEndian:
+ aValue = LittleEndian::readUint32(mCurrent);
+ break;
+ case ByteOrder::BigEndian:
+ aValue = BigEndian::readUint32(mCurrent);
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Should know the byte order by now");
+ matched = false;
+ }
+
+ if (matched) {
+ Advance(4);
+ }
+
+ return matched;
+}
+
+} // namespace mozilla::image
diff --git a/image/decoders/EXIF.h b/image/decoders/EXIF.h
new file mode 100644
index 0000000000..eb23f8d537
--- /dev/null
+++ b/image/decoders/EXIF.h
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_EXIF_h
+#define mozilla_image_decoders_EXIF_h
+
+#include <stdint.h>
+#include "nsDebug.h"
+
+#include "Orientation.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/image/Resolution.h"
+#include "mozilla/gfx/Point.h"
+
+namespace mozilla::image {
+
+enum class ByteOrder : uint8_t { Unknown, LittleEndian, BigEndian };
+
+struct EXIFData {
+ const Orientation orientation = Orientation();
+ const Resolution resolution = Resolution();
+};
+
+struct ParsedEXIFData;
+
+enum class ResolutionUnit : uint8_t {
+ Dpi,
+ Dpcm,
+};
+
+class EXIFParser {
+ public:
+ static EXIFData Parse(const uint8_t* aData, const uint32_t aLength,
+ const gfx::IntSize& aRealImageSize) {
+ EXIFParser parser;
+ return parser.ParseEXIF(aData, aLength, aRealImageSize);
+ }
+
+ private:
+ EXIFParser()
+ : mStart(nullptr),
+ mCurrent(nullptr),
+ mLength(0),
+ mRemainingLength(0),
+ mByteOrder(ByteOrder::Unknown) {}
+
+ EXIFData ParseEXIF(const uint8_t* aData, const uint32_t aLength,
+ const gfx::IntSize& aRealImageSize);
+ bool ParseEXIFHeader();
+ bool ParseTIFFHeader(uint32_t& aIFD0OffsetOut);
+
+ void ParseIFD(ParsedEXIFData&, uint32_t aDepth = 0);
+ bool ParseOrientation(uint16_t aType, uint32_t aCount, Orientation&);
+ bool ParseResolution(uint16_t aType, uint32_t aCount, Maybe<float>&);
+ bool ParseResolutionUnit(uint16_t aType, uint32_t aCount,
+ Maybe<ResolutionUnit>&);
+ bool ParseDimension(uint16_t aType, uint32_t aCount, Maybe<uint32_t>&);
+
+ bool Initialize(const uint8_t* aData, const uint32_t aLength);
+ void Advance(const uint32_t aDistance);
+ void JumpTo(const uint32_t aOffset);
+
+ uint32_t CurrentOffset() const { return mCurrent - mStart; }
+
+ class ScopedJump {
+ EXIFParser& mParser;
+ uint32_t mOldOffset;
+
+ public:
+ ScopedJump(EXIFParser& aParser, uint32_t aOffset)
+ : mParser(aParser), mOldOffset(aParser.CurrentOffset()) {
+ mParser.JumpTo(aOffset);
+ }
+
+ ~ScopedJump() { mParser.JumpTo(mOldOffset); }
+ };
+
+ bool MatchString(const char* aString, const uint32_t aLength);
+ bool MatchUInt16(const uint16_t aValue);
+ bool ReadUInt16(uint16_t& aOut);
+ bool ReadUInt32(uint32_t& aOut);
+ bool ReadRational(float& aOut);
+
+ const uint8_t* mStart;
+ const uint8_t* mCurrent;
+ uint32_t mLength;
+ uint32_t mRemainingLength;
+ ByteOrder mByteOrder;
+};
+
+} // namespace mozilla::image
+
+#endif // mozilla_image_decoders_EXIF_h
diff --git a/image/decoders/GIF2.h b/image/decoders/GIF2.h
new file mode 100644
index 0000000000..c0c6bf0fde
--- /dev/null
+++ b/image/decoders/GIF2.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_GIF2_H
+#define mozilla_image_decoders_GIF2_H
+
+#define MAX_LZW_BITS 12
+#define MAX_BITS 4097 // 2^MAX_LZW_BITS+1
+#define MAX_COLORS 256
+#define MIN_HOLD_SIZE 256
+
+enum { GIF_TRAILER = 0x3B }; // ';'
+enum { GIF_IMAGE_SEPARATOR = 0x2C }; // ','
+enum { GIF_EXTENSION_INTRODUCER = 0x21 }; // '!'
+enum { GIF_GRAPHIC_CONTROL_LABEL = 0xF9 };
+enum { GIF_APPLICATION_EXTENSION_LABEL = 0xFF };
+
+// A GIF decoder's state
+typedef struct gif_struct {
+ // LZW decoder state machine
+ uint8_t* stackp; // Current stack pointer
+ int datasize;
+ int codesize;
+ int codemask;
+ int avail; // Index of next available slot in dictionary
+ int oldcode;
+ uint8_t firstchar;
+ int bits; // Number of unread bits in "datum"
+ int32_t datum; // 32-bit input buffer
+
+ // Output state machine
+ int64_t pixels_remaining; // Pixels remaining to be output.
+
+ // Parameters for image frame currently being decoded
+ int tpixel; // Index of transparent pixel
+ int32_t disposal_method; // Restore to background, leave in place, etc.
+ uint32_t* local_colormap; // Per-image colormap
+ uint32_t local_colormap_buffer_size; // Size of the buffer containing the
+ // local colormap.
+ int local_colormap_size; // Size of local colormap array.
+ uint32_t delay_time; // Display time, in milliseconds,
+ // for this image in a multi-image GIF
+
+ // Global (multi-image) state
+ int version; // Either 89 for GIF89 or 87 for GIF87
+ int32_t screen_width; // Logical screen width & height
+ int32_t screen_height;
+ uint8_t global_colormap_depth; // Depth of global colormap array
+ uint16_t global_colormap_count; // Number of colors in global colormap
+ int images_decoded; // Counts images for multi-part GIFs
+ int loop_count; // Netscape specific extension block to control
+ // the number of animation loops a GIF
+ // renders.
+
+ bool is_transparent; // TRUE, if tpixel is valid
+
+ uint16_t prefix[MAX_BITS]; // LZW decoding tables
+ uint32_t global_colormap[MAX_COLORS]; // Default colormap if local not
+ // supplied
+ uint8_t suffix[MAX_BITS]; // LZW decoding tables
+ uint8_t stack[MAX_BITS]; // Base of LZW decoder stack
+
+} gif_struct;
+
+#endif // mozilla_image_decoders_GIF2_H
diff --git a/image/decoders/iccjpeg.c b/image/decoders/iccjpeg.c
new file mode 100644
index 0000000000..6157fe8298
--- /dev/null
+++ b/image/decoders/iccjpeg.c
@@ -0,0 +1,184 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * iccjpeg.c
+ *
+ * This file provides code to read and write International Color Consortium
+ * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has
+ * defined a standard format for including such data in JPEG "APP2" markers.
+ * The code given here does not know anything about the internal structure
+ * of the ICC profile data; it just knows how to put the profile data into
+ * a JPEG file being written, or get it back out when reading.
+ *
+ * This code depends on new features added to the IJG JPEG library as of
+ * IJG release 6b; it will not compile or work with older IJG versions.
+ *
+ * NOTE: this code would need surgery to work on 16-bit-int machines
+ * with ICC profiles exceeding 64K bytes in size. If you need to do that,
+ * change all the "unsigned int" variables to "INT32". You'll also need
+ * to find a malloc() replacement that can allocate more than 64K.
+ */
+
+#include "iccjpeg.h"
+#include <stdlib.h> /* define malloc() */
+
+/*
+ * Since an ICC profile can be larger than the maximum size of a JPEG marker
+ * (64K), we need provisions to split it into multiple markers. The format
+ * defined by the ICC specifies one or more APP2 markers containing the
+ * following data:
+ * Identifying string ASCII "ICC_PROFILE\0" (12 bytes)
+ * Marker sequence number 1 for first APP2, 2 for next, etc (1 byte)
+ * Number of markers Total number of APP2's used (1 byte)
+ * Profile data (remainder of APP2 data)
+ * Decoders should use the marker sequence numbers to reassemble the profile,
+ * rather than assuming that the APP2 markers appear in the correct sequence.
+ */
+
+#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */
+#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */
+#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */
+#define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)
+
+/*
+ * Prepare for reading an ICC profile
+ */
+
+void setup_read_icc_profile(j_decompress_ptr cinfo) {
+ /* Tell the library to keep any APP2 data it may find */
+ jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF);
+}
+
+/*
+ * Handy subroutine to test whether a saved marker is an ICC profile marker.
+ */
+
+static boolean marker_is_icc(jpeg_saved_marker_ptr marker) {
+ return marker->marker == ICC_MARKER &&
+ marker->data_length >= ICC_OVERHEAD_LEN &&
+ /* verify the identifying string */
+ GETJOCTET(marker->data[0]) == 0x49 &&
+ GETJOCTET(marker->data[1]) == 0x43 &&
+ GETJOCTET(marker->data[2]) == 0x43 &&
+ GETJOCTET(marker->data[3]) == 0x5F &&
+ GETJOCTET(marker->data[4]) == 0x50 &&
+ GETJOCTET(marker->data[5]) == 0x52 &&
+ GETJOCTET(marker->data[6]) == 0x4F &&
+ GETJOCTET(marker->data[7]) == 0x46 &&
+ GETJOCTET(marker->data[8]) == 0x49 &&
+ GETJOCTET(marker->data[9]) == 0x4C &&
+ GETJOCTET(marker->data[10]) == 0x45 &&
+ GETJOCTET(marker->data[11]) == 0x0;
+}
+
+/*
+ * See if there was an ICC profile in the JPEG file being read;
+ * if so, reassemble and return the profile data.
+ *
+ * TRUE is returned if an ICC profile was found, FALSE if not.
+ * If TRUE is returned, *icc_data_ptr is set to point to the
+ * returned data, and *icc_data_len is set to its length.
+ *
+ * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc()
+ * and must be freed by the caller with free() when the caller no longer
+ * needs it. (Alternatively, we could write this routine to use the
+ * IJG library's memory allocator, so that the data would be freed implicitly
+ * at jpeg_finish_decompress() time. But it seems likely that many apps
+ * will prefer to have the data stick around after decompression finishes.)
+ *
+ * NOTE: if the file contains invalid ICC APP2 markers, we just silently
+ * return FALSE. You might want to issue an error message instead.
+ */
+
+boolean read_icc_profile(j_decompress_ptr cinfo, JOCTET** icc_data_ptr,
+ unsigned int* icc_data_len) {
+ jpeg_saved_marker_ptr marker;
+ int num_markers = 0;
+ int seq_no;
+ JOCTET* icc_data;
+ unsigned int total_length;
+#define MAX_SEQ_NO 255 /* sufficient since marker numbers are bytes */
+ char marker_present[MAX_SEQ_NO + 1]; /* 1 if marker found */
+ unsigned int data_length[MAX_SEQ_NO + 1]; /* size of profile data in marker */
+ unsigned int data_offset[MAX_SEQ_NO + 1]; /* offset for data in marker */
+
+ *icc_data_ptr = NULL; /* avoid confusion if FALSE return */
+ *icc_data_len = 0;
+
+ /* This first pass over the saved markers discovers whether there are
+ * any ICC markers and verifies the consistency of the marker numbering.
+ */
+
+ for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++) {
+ marker_present[seq_no] = 0;
+ }
+
+ for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
+ if (marker_is_icc(marker)) {
+ if (num_markers == 0) {
+ num_markers = GETJOCTET(marker->data[13]);
+ } else if (num_markers != GETJOCTET(marker->data[13])) {
+ return FALSE; /* inconsistent num_markers fields */
+ }
+ seq_no = GETJOCTET(marker->data[12]);
+ if (seq_no <= 0 || seq_no > num_markers) {
+ return FALSE; /* bogus sequence number */
+ }
+ if (marker_present[seq_no]) {
+ return FALSE; /* duplicate sequence numbers */
+ }
+ marker_present[seq_no] = 1;
+ data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
+ }
+ }
+
+ if (num_markers == 0) {
+ return FALSE;
+ }
+
+ /* Check for missing markers, count total space needed,
+ * compute offset of each marker's part of the data.
+ */
+
+ total_length = 0;
+ for (seq_no = 1; seq_no <= num_markers; seq_no++) {
+ if (marker_present[seq_no] == 0) {
+ return FALSE; /* missing sequence number */
+ }
+ data_offset[seq_no] = total_length;
+ total_length += data_length[seq_no];
+ }
+
+ if (total_length <= 0) {
+ return FALSE; /* found only empty markers? */
+ }
+
+ /* Allocate space for assembled data */
+ icc_data = (JOCTET*)malloc(total_length * sizeof(JOCTET));
+ if (icc_data == NULL) {
+ return FALSE; /* oops, out of memory */
+ }
+
+ /* and fill it in */
+ for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
+ if (marker_is_icc(marker)) {
+ JOCTET FAR* src_ptr;
+ JOCTET* dst_ptr;
+ unsigned int length;
+ seq_no = GETJOCTET(marker->data[12]);
+ dst_ptr = icc_data + data_offset[seq_no];
+ src_ptr = marker->data + ICC_OVERHEAD_LEN;
+ length = data_length[seq_no];
+ while (length--) {
+ *dst_ptr++ = *src_ptr++;
+ }
+ }
+ }
+
+ *icc_data_ptr = icc_data;
+ *icc_data_len = total_length;
+
+ return TRUE;
+}
diff --git a/image/decoders/iccjpeg.h b/image/decoders/iccjpeg.h
new file mode 100644
index 0000000000..4d48144a23
--- /dev/null
+++ b/image/decoders/iccjpeg.h
@@ -0,0 +1,65 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * iccjpeg.h
+ *
+ * This file provides code to read and write International Color Consortium
+ * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has
+ * defined a standard format for including such data in JPEG "APP2" markers.
+ * The code given here does not know anything about the internal structure
+ * of the ICC profile data; it just knows how to put the profile data into
+ * a JPEG file being written, or get it back out when reading.
+ *
+ * This code depends on new features added to the IJG JPEG library as of
+ * IJG release 6b; it will not compile or work with older IJG versions.
+ *
+ * NOTE: this code would need surgery to work on 16-bit-int machines
+ * with ICC profiles exceeding 64K bytes in size. See iccprofile.c
+ * for details.
+ */
+
+#ifndef mozilla_image_decoders_iccjpeg_h
+#define mozilla_image_decoders_iccjpeg_h
+
+#include <stdio.h> /* needed to define "FILE", "NULL" */
+#include "jpeglib.h"
+
+/*
+ * Reading a JPEG file that may contain an ICC profile requires two steps:
+ *
+ * 1. After jpeg_create_decompress() but before jpeg_read_header(),
+ * call setup_read_icc_profile(). This routine tells the IJG library
+ * to save in memory any APP2 markers it may find in the file.
+ *
+ * 2. After jpeg_read_header(), call read_icc_profile() to find out
+ * whether there was a profile and obtain it if so.
+ */
+
+/*
+ * Prepare for reading an ICC profile
+ */
+
+extern void setup_read_icc_profile JPP((j_decompress_ptr cinfo));
+
+/*
+ * See if there was an ICC profile in the JPEG file being read;
+ * if so, reassemble and return the profile data.
+ *
+ * TRUE is returned if an ICC profile was found, FALSE if not.
+ * If TRUE is returned, *icc_data_ptr is set to point to the
+ * returned data, and *icc_data_len is set to its length.
+ *
+ * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc()
+ * and must be freed by the caller with free() when the caller no longer
+ * needs it. (Alternatively, we could write this routine to use the
+ * IJG library's memory allocator, so that the data would be freed implicitly
+ * at jpeg_finish_decompress() time. But it seems likely that many apps
+ * will prefer to have the data stick around after decompression finishes.)
+ */
+
+extern boolean read_icc_profile JPP((j_decompress_ptr cinfo,
+ JOCTET** icc_data_ptr,
+ unsigned int* icc_data_len));
+#endif // mozilla_image_decoders_iccjpeg_h
diff --git a/image/decoders/icon/android/moz.build b/image/decoders/icon/android/moz.build
new file mode 100644
index 0000000000..a99ae228d4
--- /dev/null
+++ b/image/decoders/icon/android/moz.build
@@ -0,0 +1,13 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+SOURCES += [
+ "nsIconChannel.cpp",
+]
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+FINAL_LIBRARY = "xul"
diff --git a/image/decoders/icon/android/nsIconChannel.cpp b/image/decoders/icon/android/nsIconChannel.cpp
new file mode 100644
index 0000000000..7599cf2bb7
--- /dev/null
+++ b/image/decoders/icon/android/nsIconChannel.cpp
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <stdlib.h>
+#include "mozilla/gfx/Swizzle.h"
+#include "mozilla/dom/ContentChild.h"
+#include "mozilla/NullPrincipal.h"
+#include "nsMimeTypes.h"
+#include "nsXULAppAPI.h"
+#include "AndroidBridge.h"
+#include "nsIconChannel.h"
+#include "nsIIconURI.h"
+#include "nsIStringStream.h"
+#include "nsNetUtil.h"
+#include "nsComponentManagerUtils.h"
+
+NS_IMPL_ISUPPORTS(nsIconChannel, nsIRequest, nsIChannel)
+
+using namespace mozilla;
+using mozilla::dom::ContentChild;
+
+static nsresult GetIconForExtension(const nsACString& aFileExt,
+ uint32_t aIconSize, uint8_t* const aBuf) {
+ if (!AndroidBridge::Bridge()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ AndroidBridge::Bridge()->GetIconForExtension(aFileExt, aIconSize, aBuf);
+
+ return NS_OK;
+}
+
+static nsresult CallRemoteGetIconForExtension(const nsACString& aFileExt,
+ uint32_t aIconSize,
+ uint8_t* const aBuf) {
+ NS_ENSURE_TRUE(aBuf != nullptr, NS_ERROR_NULL_POINTER);
+
+ // An array has to be used to get data from remote process
+ nsTArray<uint8_t> bits;
+ uint32_t bufSize = aIconSize * aIconSize * 4;
+
+ if (!ContentChild::GetSingleton()->SendGetIconForExtension(
+ PromiseFlatCString(aFileExt), aIconSize, &bits)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ NS_ASSERTION(bits.Length() == bufSize, "Pixels array is incomplete");
+ if (bits.Length() != bufSize) {
+ return NS_ERROR_FAILURE;
+ }
+
+ memcpy(aBuf, bits.Elements(), bufSize);
+
+ return NS_OK;
+}
+
+static nsresult moz_icon_to_channel(nsIURI* aURI, const nsACString& aFileExt,
+ uint32_t aIconSize, nsIChannel** aChannel) {
+ NS_ENSURE_TRUE(aIconSize < 256 && aIconSize > 0, NS_ERROR_UNEXPECTED);
+
+ int width = aIconSize;
+ int height = aIconSize;
+
+ // moz-icon data should have two bytes for the size,
+ // then the ARGB pixel values with pre-multiplied Alpha
+ const int channels = 4;
+ CheckedInt32 buf_size =
+ 4 + channels * CheckedInt32(height) * CheckedInt32(width);
+ if (!buf_size.isValid()) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ uint8_t* const buf = (uint8_t*)moz_xmalloc(buf_size.value());
+ uint8_t* out = buf;
+
+ *(out++) = width;
+ *(out++) = height;
+ *(out++) = uint8_t(mozilla::gfx::SurfaceFormat::R8G8B8A8);
+
+ // Set all bits to ensure in nsIconDecoder we color manage and premultiply.
+ *(out++) = 0xFF;
+
+ nsresult rv;
+ if (XRE_IsParentProcess()) {
+ rv = GetIconForExtension(aFileExt, aIconSize, out);
+ } else {
+ rv = CallRemoteGetIconForExtension(aFileExt, aIconSize, out);
+ }
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIStringInputStream> stream =
+ do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = stream->AdoptData((char*)buf, buf_size.value());
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // nsIconProtocolHandler::NewChannel will provide the correct loadInfo for
+ // this iconChannel. Use the most restrictive security settings for the
+ // temporary loadInfo to make sure the channel can not be opened.
+ nsCOMPtr<nsIPrincipal> nullPrincipal =
+ NullPrincipal::CreateWithoutOriginAttributes();
+ return NS_NewInputStreamChannel(
+ aChannel, aURI, stream.forget(), nullPrincipal,
+ nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
+ nsIContentPolicy::TYPE_INTERNAL_IMAGE, nsLiteralCString(IMAGE_ICON_MS));
+}
+
+nsresult nsIconChannel::Init(nsIURI* aURI) {
+ nsCOMPtr<nsIMozIconURI> iconURI = do_QueryInterface(aURI);
+ NS_ASSERTION(iconURI, "URI is not an nsIMozIconURI");
+
+ nsAutoCString stockIcon;
+ iconURI->GetStockIcon(stockIcon);
+
+ uint32_t desiredImageSize;
+ iconURI->GetImageSize(&desiredImageSize);
+
+ nsAutoCString iconFileExt;
+ iconURI->GetFileExtension(iconFileExt);
+
+ return moz_icon_to_channel(iconURI, iconFileExt, desiredImageSize,
+ getter_AddRefs(mRealChannel));
+}
diff --git a/image/decoders/icon/android/nsIconChannel.h b/image/decoders/icon/android/nsIconChannel.h
new file mode 100644
index 0000000000..e25196c6ee
--- /dev/null
+++ b/image/decoders/icon/android/nsIconChannel.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_icon_android_nsIconChannel_h
+#define mozilla_image_decoders_icon_android_nsIconChannel_h
+
+#include "mozilla/Attributes.h"
+
+#include "nsIChannel.h"
+#include "nsIURI.h"
+#include "nsCOMPtr.h"
+
+/**
+ * This class is the Android implementation of nsIconChannel.
+ * It asks Android for an icon, and creates a new channel for
+ * that file to which all calls will be proxied.
+ */
+class nsIconChannel final : public nsIChannel {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_FORWARD_NSIREQUEST(mRealChannel->)
+ NS_FORWARD_NSICHANNEL(mRealChannel->)
+
+ nsIconChannel() {}
+
+ /**
+ * Called by nsIconProtocolHandler after it creates this channel.
+ * Must be called before calling any other function on this object.
+ * If this method fails, no other function must be called on this object.
+ */
+ nsresult Init(nsIURI* aURI);
+
+ private:
+ ~nsIconChannel() {}
+
+ /**
+ * The channel to the temp icon file (e.g. to /tmp/2qy9wjqw.html).
+ * Will always be non-null after a successful Init.
+ */
+ nsCOMPtr<nsIChannel> mRealChannel;
+};
+
+#endif // mozilla_image_decoders_icon_android_nsIconChannel_h
diff --git a/image/decoders/icon/components.conf b/image/decoders/icon/components.conf
new file mode 100644
index 0000000000..68bff8e231
--- /dev/null
+++ b/image/decoders/icon/components.conf
@@ -0,0 +1,29 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+Classes = [
+ {
+ 'cid': '{d0f9db12-249c-11d5-9905-001083010e9b}',
+ 'contract_ids': ['@mozilla.org/network/protocol;1?name=moz-icon'],
+ 'type': 'nsIconProtocolHandler',
+ 'headers': ['/image/decoders/icon/nsIconProtocolHandler.h'],
+ 'protocol_config': {
+ 'scheme': 'moz-icon',
+ 'flags': [
+ 'URI_NORELATIVE',
+ 'URI_NOAUTH',
+ 'URI_IS_UI_RESOURCE',
+ 'URI_IS_LOCAL_RESOURCE',
+ ],
+ 'default_port': 0,
+ },
+ },
+ {
+ 'cid': '{1460df3b-774c-4205-8349-838e507c3ef9}',
+ 'type': 'nsMozIconURI::Mutator',
+ 'headers': ['/image/decoders/icon/nsIconURI.h'],
+ },
+]
diff --git a/image/decoders/icon/gtk/moz.build b/image/decoders/icon/gtk/moz.build
new file mode 100644
index 0000000000..3eac86b6ba
--- /dev/null
+++ b/image/decoders/icon/gtk/moz.build
@@ -0,0 +1,20 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+SOURCES += [
+ "nsIconChannel.cpp",
+]
+
+EXPORTS += [
+ "nsIconChannel.h",
+]
+
+FINAL_LIBRARY = "xul"
+
+if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
+ CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"]
+
+include("/ipc/chromium/chromium-config.mozbuild")
diff --git a/image/decoders/icon/gtk/nsIconChannel.cpp b/image/decoders/icon/gtk/nsIconChannel.cpp
new file mode 100644
index 0000000000..2b8b958b9e
--- /dev/null
+++ b/image/decoders/icon/gtk/nsIconChannel.cpp
@@ -0,0 +1,483 @@
+/* vim:set ts=2 sw=2 sts=2 cin et: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIconChannel.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "mozilla/DebugOnly.h"
+#include "mozilla/EndianUtils.h"
+#include "mozilla/NullPrincipal.h"
+#include "mozilla/CheckedInt.h"
+#include "mozilla/dom/ContentChild.h"
+#include "mozilla/gfx/Swizzle.h"
+#include "mozilla/ipc/ByteBuf.h"
+#include <algorithm>
+
+#include <gio/gio.h>
+
+#include <gtk/gtk.h>
+
+#include "nsMimeTypes.h"
+#include "nsIMIMEService.h"
+
+#include "nsServiceManagerUtils.h"
+
+#include "nsNetUtil.h"
+#include "nsComponentManagerUtils.h"
+#include "nsIStringStream.h"
+#include "nsServiceManagerUtils.h"
+#include "nsIURL.h"
+#include "nsIPipe.h"
+#include "nsIAsyncInputStream.h"
+#include "nsIAsyncOutputStream.h"
+#include "prlink.h"
+#include "gfxPlatform.h"
+
+using mozilla::CheckedInt32;
+using mozilla::ipc::ByteBuf;
+
+NS_IMPL_ISUPPORTS(nsIconChannel, nsIRequest, nsIChannel)
+
+static nsresult MozGdkPixbufToByteBuf(GdkPixbuf* aPixbuf, ByteBuf* aByteBuf) {
+ int width = gdk_pixbuf_get_width(aPixbuf);
+ int height = gdk_pixbuf_get_height(aPixbuf);
+ NS_ENSURE_TRUE(height < 256 && width < 256 && height > 0 && width > 0 &&
+ gdk_pixbuf_get_colorspace(aPixbuf) == GDK_COLORSPACE_RGB &&
+ gdk_pixbuf_get_bits_per_sample(aPixbuf) == 8 &&
+ gdk_pixbuf_get_has_alpha(aPixbuf) &&
+ gdk_pixbuf_get_n_channels(aPixbuf) == 4,
+ NS_ERROR_UNEXPECTED);
+
+ const int n_channels = 4;
+ CheckedInt32 buf_size =
+ 4 + n_channels * CheckedInt32(height) * CheckedInt32(width);
+ if (!buf_size.isValid()) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ uint8_t* const buf = (uint8_t*)moz_xmalloc(buf_size.value());
+ uint8_t* out = buf;
+
+ *(out++) = width;
+ *(out++) = height;
+ *(out++) = uint8_t(mozilla::gfx::SurfaceFormat::OS_RGBA);
+
+ // Set all bits to ensure in nsIconDecoder we color manage and premultiply.
+ *(out++) = 0xFF;
+
+ const guchar* const pixels = gdk_pixbuf_get_pixels(aPixbuf);
+ int instride = gdk_pixbuf_get_rowstride(aPixbuf);
+ int outstride = width * n_channels;
+
+ // encode the RGB data and the A data and adjust the stride as necessary.
+ mozilla::gfx::SwizzleData(pixels, instride,
+ mozilla::gfx::SurfaceFormat::R8G8B8A8, out,
+ outstride, mozilla::gfx::SurfaceFormat::OS_RGBA,
+ mozilla::gfx::IntSize(width, height));
+
+ *aByteBuf = ByteBuf(buf, buf_size.value(), buf_size.value());
+ return NS_OK;
+}
+
+static nsresult ByteBufToStream(ByteBuf&& aBuf, nsIInputStream** aStream) {
+ nsresult rv;
+ nsCOMPtr<nsIStringInputStream> stream =
+ do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
+
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ // stream takes ownership of buf and will free it on destruction.
+ // This function cannot fail.
+ rv = stream->AdoptData(reinterpret_cast<char*>(aBuf.mData), aBuf.mLen);
+ MOZ_ASSERT(CheckedInt32(aBuf.mLen).isValid(),
+ "aBuf.mLen should fit in int32_t");
+ aBuf.mData = nullptr;
+
+ // If this no longer holds then re-examine buf's lifetime.
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ stream.forget(aStream);
+ return NS_OK;
+}
+
+static nsresult StreamToChannel(already_AddRefed<nsIInputStream> aStream,
+ nsIURI* aURI, nsIChannel** aChannel) {
+ // nsIconProtocolHandler::NewChannel will provide the correct loadInfo for
+ // this iconChannel. Use the most restrictive security settings for the
+ // temporary loadInfo to make sure the channel can not be opened.
+ nsCOMPtr<nsIPrincipal> nullPrincipal =
+ mozilla::NullPrincipal::CreateWithoutOriginAttributes();
+ return NS_NewInputStreamChannel(
+ aChannel, aURI, std::move(aStream), nullPrincipal,
+ nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
+ nsIContentPolicy::TYPE_INTERNAL_IMAGE, nsLiteralCString(IMAGE_ICON_MS));
+}
+
+static GtkWidget* gProtoWindow = nullptr;
+static GtkWidget* gStockImageWidget = nullptr;
+
+static void ensure_stock_image_widget() {
+ // Only the style of the GtkImage needs to be used, but the widget is kept
+ // to track dynamic style changes.
+ if (!gProtoWindow) {
+ gProtoWindow = gtk_window_new(GTK_WINDOW_POPUP);
+ GtkWidget* protoLayout = gtk_fixed_new();
+ gtk_container_add(GTK_CONTAINER(gProtoWindow), protoLayout);
+
+ gStockImageWidget = gtk_image_new();
+ gtk_container_add(GTK_CONTAINER(protoLayout), gStockImageWidget);
+
+ gtk_widget_ensure_style(gStockImageWidget);
+ }
+}
+
+static GtkIconSize moz_gtk_icon_size(const char* name) {
+ if (strcmp(name, "button") == 0) {
+ return GTK_ICON_SIZE_BUTTON;
+ }
+
+ if (strcmp(name, "menu") == 0) {
+ return GTK_ICON_SIZE_MENU;
+ }
+
+ if (strcmp(name, "toolbar") == 0) {
+ return GTK_ICON_SIZE_LARGE_TOOLBAR;
+ }
+
+ if (strcmp(name, "toolbarsmall") == 0) {
+ return GTK_ICON_SIZE_SMALL_TOOLBAR;
+ }
+
+ if (strcmp(name, "dnd") == 0) {
+ return GTK_ICON_SIZE_DND;
+ }
+
+ if (strcmp(name, "dialog") == 0) {
+ return GTK_ICON_SIZE_DIALOG;
+ }
+
+ return GTK_ICON_SIZE_MENU;
+}
+
+static int32_t GetIconSize(nsIMozIconURI* aIconURI) {
+ nsAutoCString iconSizeString;
+
+ aIconURI->GetIconSize(iconSizeString);
+ if (iconSizeString.IsEmpty()) {
+ uint32_t size;
+ mozilla::DebugOnly<nsresult> rv = aIconURI->GetImageSize(&size);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "GetImageSize failed");
+ return size;
+ }
+ int size;
+
+ GtkIconSize icon_size = moz_gtk_icon_size(iconSizeString.get());
+ gtk_icon_size_lookup(icon_size, &size, nullptr);
+ return size;
+}
+
+/* Scale icon buffer to preferred size */
+static nsresult ScaleIconBuf(GdkPixbuf** aBuf, int32_t iconSize) {
+ // Scale buffer only if width or height differ from preferred size
+ if (gdk_pixbuf_get_width(*aBuf) != iconSize &&
+ gdk_pixbuf_get_height(*aBuf) != iconSize) {
+ GdkPixbuf* scaled =
+ gdk_pixbuf_scale_simple(*aBuf, iconSize, iconSize, GDK_INTERP_BILINEAR);
+ // replace original buffer by scaled
+ g_object_unref(*aBuf);
+ *aBuf = scaled;
+ if (!scaled) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ return NS_OK;
+}
+
+/* static */
+nsresult nsIconChannel::GetIconWithGIO(nsIMozIconURI* aIconURI,
+ ByteBuf* aDataOut) {
+ GIcon* icon = nullptr;
+ nsCOMPtr<nsIURL> fileURI;
+
+ // Read icon content
+ aIconURI->GetIconURL(getter_AddRefs(fileURI));
+
+ // Get icon for file specified by URI
+ if (fileURI) {
+ nsAutoCString spec;
+ fileURI->GetAsciiSpec(spec);
+ if (fileURI->SchemeIs("file")) {
+ GFile* file = g_file_new_for_uri(spec.get());
+ GFileInfo* fileInfo =
+ g_file_query_info(file, G_FILE_ATTRIBUTE_STANDARD_ICON,
+ G_FILE_QUERY_INFO_NONE, nullptr, nullptr);
+ g_object_unref(file);
+ if (fileInfo) {
+ // icon from g_content_type_get_icon doesn't need unref
+ icon = g_file_info_get_icon(fileInfo);
+ if (icon) {
+ g_object_ref(icon);
+ }
+ g_object_unref(fileInfo);
+ }
+ }
+ }
+
+ // Try to get icon by using MIME type
+ if (!icon) {
+ nsAutoCString type;
+ aIconURI->GetContentType(type);
+ // Try to get MIME type from file extension by using nsIMIMEService
+ if (type.IsEmpty()) {
+ nsCOMPtr<nsIMIMEService> ms(do_GetService("@mozilla.org/mime;1"));
+ if (ms) {
+ nsAutoCString fileExt;
+ aIconURI->GetFileExtension(fileExt);
+ ms->GetTypeFromExtension(fileExt, type);
+ }
+ }
+ char* ctype = nullptr; // character representation of content type
+ if (!type.IsEmpty()) {
+ ctype = g_content_type_from_mime_type(type.get());
+ }
+ if (ctype) {
+ icon = g_content_type_get_icon(ctype);
+ g_free(ctype);
+ }
+ }
+
+ // Get default icon theme
+ GtkIconTheme* iconTheme = gtk_icon_theme_get_default();
+ GtkIconInfo* iconInfo = nullptr;
+ // Get icon size
+ int32_t iconSize = GetIconSize(aIconURI);
+
+ if (icon) {
+ // Use icon and theme to get GtkIconInfo
+ iconInfo = gtk_icon_theme_lookup_by_gicon(iconTheme, icon, iconSize,
+ (GtkIconLookupFlags)0);
+ g_object_unref(icon);
+ }
+
+ if (!iconInfo) {
+ // Mozilla's mimetype lookup failed. Try the "unknown" icon.
+ iconInfo = gtk_icon_theme_lookup_icon(iconTheme, "unknown", iconSize,
+ (GtkIconLookupFlags)0);
+ if (!iconInfo) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ }
+
+ // Create a GdkPixbuf buffer containing icon and scale it
+ GdkPixbuf* buf = gtk_icon_info_load_icon(iconInfo, nullptr);
+ gtk_icon_info_free(iconInfo);
+ if (!buf) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsresult rv = ScaleIconBuf(&buf, iconSize);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = MozGdkPixbufToByteBuf(buf, aDataOut);
+ g_object_unref(buf);
+ return rv;
+}
+
+/* static */
+nsresult nsIconChannel::GetIcon(nsIURI* aURI, ByteBuf* aDataOut) {
+ nsCOMPtr<nsIMozIconURI> iconURI = do_QueryInterface(aURI);
+ NS_ASSERTION(iconURI, "URI is not an nsIMozIconURI");
+
+ if (!iconURI) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ if (gfxPlatform::IsHeadless()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ nsAutoCString stockIcon;
+ iconURI->GetStockIcon(stockIcon);
+ if (stockIcon.IsEmpty()) {
+ return GetIconWithGIO(iconURI, aDataOut);
+ }
+
+ // Search for stockIcon
+ nsAutoCString iconSizeString;
+ iconURI->GetIconSize(iconSizeString);
+
+ nsAutoCString iconStateString;
+ iconURI->GetIconState(iconStateString);
+
+ GtkIconSize icon_size = moz_gtk_icon_size(iconSizeString.get());
+ GtkStateType state = iconStateString.EqualsLiteral("disabled")
+ ? GTK_STATE_INSENSITIVE
+ : GTK_STATE_NORMAL;
+
+ // First lookup the icon by stock id and text direction.
+ GtkTextDirection direction = GTK_TEXT_DIR_NONE;
+ if (StringEndsWith(stockIcon, "-ltr"_ns)) {
+ direction = GTK_TEXT_DIR_LTR;
+ } else if (StringEndsWith(stockIcon, "-rtl"_ns)) {
+ direction = GTK_TEXT_DIR_RTL;
+ }
+
+ bool forceDirection = direction != GTK_TEXT_DIR_NONE;
+ nsAutoCString stockID;
+ bool useIconName = false;
+ if (!forceDirection) {
+ direction = gtk_widget_get_default_direction();
+ stockID = stockIcon;
+ } else {
+ // GTK versions < 2.22 use icon names from concatenating stock id with
+ // -(rtl|ltr), which is how the moz-icon stock name is interpreted here.
+ stockID = Substring(stockIcon, 0, stockIcon.Length() - 4);
+ // However, if we lookup bidi icons by the stock name, then GTK versions
+ // >= 2.22 will use a bidi lookup convention that most icon themes do not
+ // yet follow. Therefore, we first check to see if the theme supports the
+ // old icon name as this will have bidi support (if found).
+ GtkIconTheme* icon_theme = gtk_icon_theme_get_default();
+ // Micking what gtk_icon_set_render_icon does with sizes, though it's not
+ // critical as icons will be scaled to suit size. It just means we follow
+ // the same paths and so share caches.
+ gint width, height;
+ if (gtk_icon_size_lookup(icon_size, &width, &height)) {
+ gint size = std::min(width, height);
+ // We use gtk_icon_theme_lookup_icon() without
+ // GTK_ICON_LOOKUP_USE_BUILTIN instead of gtk_icon_theme_has_icon() so
+ // we don't pick up fallback icons added by distributions for backward
+ // compatibility.
+ GtkIconInfo* icon = gtk_icon_theme_lookup_icon(
+ icon_theme, stockIcon.get(), size, (GtkIconLookupFlags)0);
+ if (icon) {
+ useIconName = true;
+ gtk_icon_info_free(icon);
+ }
+ }
+ }
+
+ ensure_stock_image_widget();
+ GtkStyle* style = gtk_widget_get_style(gStockImageWidget);
+ GtkIconSet* icon_set = nullptr;
+ if (!useIconName) {
+ icon_set = gtk_style_lookup_icon_set(style, stockID.get());
+ }
+
+ if (!icon_set) {
+ // Either we have chosen icon-name lookup for a bidi icon, or stockIcon is
+ // not a stock id so we assume it is an icon name.
+ useIconName = true;
+ // Creating a GtkIconSet is a convenient way to allow the style to
+ // render the icon, possibly with variations suitable for insensitive
+ // states.
+ icon_set = gtk_icon_set_new();
+ GtkIconSource* icon_source = gtk_icon_source_new();
+
+ gtk_icon_source_set_icon_name(icon_source, stockIcon.get());
+ gtk_icon_set_add_source(icon_set, icon_source);
+ gtk_icon_source_free(icon_source);
+ }
+
+ GdkPixbuf* icon = gtk_icon_set_render_icon(
+ icon_set, style, direction, state, icon_size, gStockImageWidget, nullptr);
+ if (useIconName) {
+ gtk_icon_set_unref(icon_set);
+ }
+
+ // According to documentation, gtk_icon_set_render_icon() never returns
+ // nullptr, but it does return nullptr when we have the problem reported
+ // here: https://bugzilla.gnome.org/show_bug.cgi?id=629878#c13
+ if (!icon) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ nsresult rv = MozGdkPixbufToByteBuf(icon, aDataOut);
+
+ g_object_unref(icon);
+
+ return rv;
+}
+
+nsresult nsIconChannel::Init(nsIURI* aURI) {
+ nsCOMPtr<nsIInputStream> stream;
+
+ using ContentChild = mozilla::dom::ContentChild;
+ if (auto* contentChild = ContentChild::GetSingleton()) {
+ // Get the icon via IPC and translate the promise of a ByteBuf
+ // into an actually-existing channel.
+ RefPtr<ContentChild::GetSystemIconPromise> icon =
+ contentChild->SendGetSystemIcon(aURI);
+ if (!icon) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsCOMPtr<nsIAsyncInputStream> inputStream;
+ nsCOMPtr<nsIAsyncOutputStream> outputStream;
+ NS_NewPipe2(getter_AddRefs(inputStream), getter_AddRefs(outputStream), true,
+ false, 0, UINT32_MAX);
+
+ // FIXME: Bug 1718324
+ // The GetSystemIcon() call will end up on the parent doing GetIcon()
+ // and by using ByteBuf we might not be immune to some deadlock, at least
+ // on paper. From analysis in
+ // https://phabricator.services.mozilla.com/D118596#3865440 we should be
+ // safe in practice, but it would be nicer to just write that differently.
+
+ icon->Then(
+ mozilla::GetCurrentSerialEventTarget(), __func__,
+ [outputStream](std::tuple<nsresult, mozilla::Maybe<ByteBuf>>&& aArg) {
+ nsresult rv = std::get<0>(aArg);
+ mozilla::Maybe<ByteBuf> bytes = std::move(std::get<1>(aArg));
+
+ if (NS_SUCCEEDED(rv)) {
+ MOZ_RELEASE_ASSERT(bytes);
+ uint32_t written;
+ rv = outputStream->Write(reinterpret_cast<char*>(bytes->mData),
+ static_cast<uint32_t>(bytes->mLen),
+ &written);
+ if (NS_SUCCEEDED(rv)) {
+ const bool wroteAll = static_cast<size_t>(written) == bytes->mLen;
+ MOZ_ASSERT(wroteAll);
+ if (!wroteAll) {
+ rv = NS_ERROR_UNEXPECTED;
+ }
+ }
+ } else {
+ MOZ_ASSERT(!bytes);
+ }
+
+ if (NS_FAILED(rv)) {
+ outputStream->CloseWithStatus(rv);
+ }
+ },
+ [outputStream](mozilla::ipc::ResponseRejectReason) {
+ outputStream->CloseWithStatus(NS_ERROR_FAILURE);
+ });
+
+ stream = inputStream.forget();
+ } else {
+ // Get the icon directly.
+ ByteBuf bytebuf;
+ nsresult rv = GetIcon(aURI, &bytebuf);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = ByteBufToStream(std::move(bytebuf), getter_AddRefs(stream));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return StreamToChannel(stream.forget(), aURI, getter_AddRefs(mRealChannel));
+}
+
+void nsIconChannel::Shutdown() {
+ if (gProtoWindow) {
+ gtk_widget_destroy(gProtoWindow);
+ gProtoWindow = nullptr;
+ gStockImageWidget = nullptr;
+ }
+}
diff --git a/image/decoders/icon/gtk/nsIconChannel.h b/image/decoders/icon/gtk/nsIconChannel.h
new file mode 100644
index 0000000000..6ad26602d0
--- /dev/null
+++ b/image/decoders/icon/gtk/nsIconChannel.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_icon_gtk_nsIconChannel_h
+#define mozilla_image_decoders_icon_gtk_nsIconChannel_h
+
+#include "mozilla/Attributes.h"
+
+#include "nsIChannel.h"
+#include "nsIURI.h"
+#include "nsIIconURI.h"
+#include "nsCOMPtr.h"
+
+namespace mozilla::ipc {
+class ByteBuf;
+}
+
+/// This class is the GTK implementation of nsIconChannel. It asks
+/// GTK for the icon, translates the pixel data in-memory into
+/// nsIconDecoder format, and proxies the nsChannel interface to a new
+/// channel returning that image.
+class nsIconChannel final : public nsIChannel {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_FORWARD_NSIREQUEST(mRealChannel->)
+ NS_FORWARD_NSICHANNEL(mRealChannel->)
+
+ nsIconChannel() {}
+
+ static void Shutdown();
+
+ /// Called by nsIconProtocolHandler after it creates this channel.
+ /// Must be called before calling any other function on this object.
+ /// If this method fails, no other function must be called on this object.
+ nsresult Init(nsIURI* aURI);
+
+ /// Obtains an icon, in nsIconDecoder format, as a ByteBuf instead
+ /// of a channel. For use with IPC.
+ static nsresult GetIcon(nsIURI* aURI, mozilla::ipc::ByteBuf* aDataOut);
+
+ private:
+ ~nsIconChannel() {}
+ /// The input stream channel which will yield the image.
+ /// Will always be non-null after a successful Init.
+ nsCOMPtr<nsIChannel> mRealChannel;
+
+ static nsresult GetIconWithGIO(nsIMozIconURI* aIconURI,
+ mozilla::ipc::ByteBuf* aDataOut);
+};
+
+#endif // mozilla_image_decoders_icon_gtk_nsIconChannel_h
diff --git a/image/decoders/icon/mac/moz.build b/image/decoders/icon/mac/moz.build
new file mode 100644
index 0000000000..3467659a8f
--- /dev/null
+++ b/image/decoders/icon/mac/moz.build
@@ -0,0 +1,13 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+SOURCES += [
+ "nsIconChannelCocoa.mm",
+]
+
+FINAL_LIBRARY = "xul"
+
+include("/ipc/chromium/chromium-config.mozbuild")
diff --git a/image/decoders/icon/mac/nsIconChannel.h b/image/decoders/icon/mac/nsIconChannel.h
new file mode 100644
index 0000000000..dca2a3c51a
--- /dev/null
+++ b/image/decoders/icon/mac/nsIconChannel.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_encoders_icon_mac_nsIconChannel_h
+#define mozilla_image_encoders_icon_mac_nsIconChannel_h
+
+#include "mozilla/Attributes.h"
+
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "nsIChannel.h"
+#include "nsILoadGroup.h"
+#include "nsILoadInfo.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIInputStreamPump.h"
+#include "nsIStreamListener.h"
+#include "nsIURI.h"
+#include "nsNetUtil.h"
+
+class nsIFile;
+
+class nsIconChannel final : public nsIChannel, public nsIStreamListener {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIREQUEST
+ NS_DECL_NSICHANNEL
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSISTREAMLISTENER
+
+ nsIconChannel();
+
+ nsresult Init(nsIURI* uri);
+
+ protected:
+ virtual ~nsIconChannel();
+
+ nsCOMPtr<nsIURI> mUrl;
+ nsCOMPtr<nsIURI> mOriginalURI;
+ nsCOMPtr<nsILoadGroup> mLoadGroup;
+ nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
+ nsCOMPtr<nsISupports> mOwner;
+ nsCOMPtr<nsILoadInfo> mLoadInfo;
+
+ nsCOMPtr<nsIInputStreamPump> mPump;
+ nsCOMPtr<nsIStreamListener> mListener;
+ bool mCanceled = false;
+
+ [[nodiscard]] nsresult MakeInputStream(nsIInputStream** _retval,
+ bool nonBlocking);
+
+ nsresult ExtractIconInfoFromUrl(nsIFile** aLocalFile,
+ uint32_t* aDesiredImageSize,
+ nsACString& aContentType,
+ nsACString& aFileExtension);
+};
+
+#endif // mozilla_image_encoders_icon_mac_nsIconChannel_h
diff --git a/image/decoders/icon/mac/nsIconChannelCocoa.mm b/image/decoders/icon/mac/nsIconChannelCocoa.mm
new file mode 100644
index 0000000000..368ecdda20
--- /dev/null
+++ b/image/decoders/icon/mac/nsIconChannelCocoa.mm
@@ -0,0 +1,505 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsContentUtils.h"
+#include "nsIconChannel.h"
+#include "mozilla/BasePrincipal.h"
+#include "mozilla/EndianUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "nsIIconURI.h"
+#include "nsIInputStream.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsString.h"
+#include "nsMimeTypes.h"
+#include "nsIURL.h"
+#include "nsNetCID.h"
+#include "nsIPipe.h"
+#include "nsIOutputStream.h"
+#include "nsCExternalHandlerService.h"
+#include "nsILocalFileMac.h"
+#include "nsIFileURL.h"
+#include "nsTArray.h"
+#include "nsObjCExceptions.h"
+#include "nsProxyRelease.h"
+#include "nsContentSecurityManager.h"
+#include "nsNetUtil.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/UniquePtrExtensions.h"
+
+#include <Cocoa/Cocoa.h>
+
+using namespace mozilla;
+
+// nsIconChannel methods
+nsIconChannel::nsIconChannel() {}
+
+nsIconChannel::~nsIconChannel() {
+ if (mLoadInfo) {
+ NS_ReleaseOnMainThread("nsIconChannel::mLoadInfo", mLoadInfo.forget());
+ }
+}
+
+NS_IMPL_ISUPPORTS(nsIconChannel, nsIChannel, nsIRequest, nsIRequestObserver, nsIStreamListener)
+
+nsresult nsIconChannel::Init(nsIURI* uri) {
+ NS_ASSERTION(uri, "no uri");
+ mUrl = uri;
+ mOriginalURI = uri;
+ nsresult rv;
+ mPump = do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv);
+ return rv;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIRequest methods:
+
+NS_IMETHODIMP
+nsIconChannel::GetName(nsACString& result) { return mUrl->GetSpec(result); }
+
+NS_IMETHODIMP
+nsIconChannel::IsPending(bool* result) { return mPump->IsPending(result); }
+
+NS_IMETHODIMP
+nsIconChannel::GetStatus(nsresult* status) { return mPump->GetStatus(status); }
+
+NS_IMETHODIMP nsIconChannel::SetCanceledReason(const nsACString& aReason) {
+ return SetCanceledReasonImpl(aReason);
+}
+
+NS_IMETHODIMP nsIconChannel::GetCanceledReason(nsACString& aReason) {
+ return GetCanceledReasonImpl(aReason);
+}
+
+NS_IMETHODIMP nsIconChannel::CancelWithReason(nsresult aStatus, const nsACString& aReason) {
+ return CancelWithReasonImpl(aStatus, aReason);
+}
+
+NS_IMETHODIMP
+nsIconChannel::Cancel(nsresult status) {
+ mCanceled = true;
+ return mPump->Cancel(status);
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetCanceled(bool* result) {
+ *result = mCanceled;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::Suspend(void) { return mPump->Suspend(); }
+
+NS_IMETHODIMP
+nsIconChannel::Resume(void) { return mPump->Resume(); }
+
+// nsIRequestObserver methods
+NS_IMETHODIMP
+nsIconChannel::OnStartRequest(nsIRequest* aRequest) {
+ if (mListener) {
+ return mListener->OnStartRequest(this);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
+ if (mListener) {
+ mListener->OnStopRequest(this, aStatus);
+ mListener = nullptr;
+ }
+
+ // Remove from load group
+ if (mLoadGroup) {
+ mLoadGroup->RemoveRequest(this, nullptr, aStatus);
+ }
+
+ return NS_OK;
+}
+
+// nsIStreamListener methods
+NS_IMETHODIMP
+nsIconChannel::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aStream, uint64_t aOffset,
+ uint32_t aCount) {
+ if (mListener) {
+ return mListener->OnDataAvailable(this, aStream, aOffset, aCount);
+ }
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIChannel methods:
+
+NS_IMETHODIMP
+nsIconChannel::GetOriginalURI(nsIURI** aURI) {
+ *aURI = mOriginalURI;
+ NS_ADDREF(*aURI);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetOriginalURI(nsIURI* aURI) {
+ NS_ENSURE_ARG_POINTER(aURI);
+ mOriginalURI = aURI;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetURI(nsIURI** aURI) {
+ *aURI = mUrl;
+ NS_IF_ADDREF(*aURI);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::Open(nsIInputStream** _retval) {
+ nsCOMPtr<nsIStreamListener> listener;
+ nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return MakeInputStream(_retval, false);
+}
+
+nsresult nsIconChannel::ExtractIconInfoFromUrl(nsIFile** aLocalFile, uint32_t* aDesiredImageSize,
+ nsACString& aContentType,
+ nsACString& aFileExtension) {
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIMozIconURI> iconURI(do_QueryInterface(mUrl, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ iconURI->GetImageSize(aDesiredImageSize);
+ iconURI->GetContentType(aContentType);
+ iconURI->GetFileExtension(aFileExtension);
+
+ nsCOMPtr<nsIURL> url;
+ rv = iconURI->GetIconURL(getter_AddRefs(url));
+ if (NS_FAILED(rv) || !url) return NS_OK;
+
+ nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(url, &rv);
+ if (NS_FAILED(rv) || !fileURL) return NS_OK;
+
+ nsCOMPtr<nsIFile> file;
+ rv = fileURL->GetFile(getter_AddRefs(file));
+ if (NS_FAILED(rv) || !file) return NS_OK;
+
+ nsCOMPtr<nsILocalFileMac> localFileMac(do_QueryInterface(file, &rv));
+ if (NS_FAILED(rv) || !localFileMac) return NS_OK;
+
+ *aLocalFile = file;
+ NS_IF_ADDREF(*aLocalFile);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::AsyncOpen(nsIStreamListener* aListener) {
+ nsCOMPtr<nsIStreamListener> listener = aListener;
+ nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
+ if (NS_FAILED(rv)) {
+ mCallbacks = nullptr;
+ return rv;
+ }
+
+ MOZ_ASSERT(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() ||
+ (mLoadInfo->GetSecurityMode() ==
+ nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL &&
+ mLoadInfo->GetLoadingPrincipal() &&
+ mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal()),
+ "security flags in loadInfo but doContentSecurityCheck() not called");
+
+ nsCOMPtr<nsIInputStream> inStream;
+ rv = MakeInputStream(getter_AddRefs(inStream), true);
+ if (NS_FAILED(rv)) {
+ mCallbacks = nullptr;
+ return rv;
+ }
+
+ // Init our stream pump
+ nsCOMPtr<nsISerialEventTarget> target =
+ nsContentUtils::GetEventTargetByLoadInfo(mLoadInfo, mozilla::TaskCategory::Other);
+ rv = mPump->Init(inStream, 0, 0, false, target);
+ if (NS_FAILED(rv)) {
+ mCallbacks = nullptr;
+ return rv;
+ }
+
+ rv = mPump->AsyncRead(this);
+ if (NS_SUCCEEDED(rv)) {
+ // Store our real listener
+ mListener = aListener;
+ // Add ourself to the load group, if available
+ if (mLoadGroup) {
+ mLoadGroup->AddRequest(this, nullptr);
+ }
+ } else {
+ mCallbacks = nullptr;
+ }
+
+ return rv;
+}
+
+nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, bool aNonBlocking) {
+ NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
+
+ nsCString contentType;
+ nsAutoCString fileExt;
+ nsCOMPtr<nsIFile> fileloc; // file we want an icon for
+ uint32_t desiredImageSize;
+ nsresult rv =
+ ExtractIconInfoFromUrl(getter_AddRefs(fileloc), &desiredImageSize, contentType, fileExt);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool fileExists = false;
+ if (fileloc) {
+ fileloc->Exists(&fileExists);
+ }
+
+ NSImage* iconImage = nil;
+
+ // first try to get the icon from the file if it exists
+ if (fileExists) {
+ nsCOMPtr<nsILocalFileMac> localFileMac(do_QueryInterface(fileloc, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ CFURLRef macURL;
+ if (NS_SUCCEEDED(localFileMac->GetCFURL(&macURL))) {
+ iconImage = [[NSWorkspace sharedWorkspace] iconForFile:[(NSURL*)macURL path]];
+ ::CFRelease(macURL);
+ }
+ }
+
+ // if we don't have an icon yet try to get one by extension
+ if (!iconImage && !fileExt.IsEmpty()) {
+ NSString* fileExtension = [NSString stringWithUTF8String:fileExt.get()];
+ iconImage = [[NSWorkspace sharedWorkspace] iconForFileType:fileExtension];
+ }
+
+ // If we still don't have an icon, get the generic document icon.
+ if (!iconImage) {
+ iconImage = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeUnknown];
+ }
+
+ if (!iconImage) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (desiredImageSize > 255) {
+ // The Icon image format represents width and height as u8, so it does not
+ // allow for images sized 256 or more.
+ return NS_ERROR_FAILURE;
+ }
+
+ // Set the actual size to *twice* the requested size.
+ // We do this because our UI doesn't take the window's device pixel ratio into
+ // account when it requests these icons; e.g. it will request an icon with
+ // size 16, place it in a 16x16 CSS pixel sized image, and then display it in
+ // a window on a HiDPI screen where the icon now covers 32x32 physical screen
+ // pixels. So we just always double the size here in order to prevent blurriness.
+ uint32_t size = (desiredImageSize < 128) ? desiredImageSize * 2 : desiredImageSize;
+ uint32_t width = size;
+ uint32_t height = size;
+
+ // The "image format" we're outputting here (and which gets decoded by
+ // nsIconDecoder) has the following format:
+ // - 1 byte for the image width, as u8
+ // - 1 byte for the image height, as u8
+ // - the raw image data as BGRA, width * height * 4 bytes.
+ size_t bufferCapacity = 4 + width * height * 4;
+ UniquePtr<uint8_t[]> fileBuf = MakeUniqueFallible<uint8_t[]>(bufferCapacity);
+ if (NS_WARN_IF(!fileBuf)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ fileBuf[0] = uint8_t(width);
+ fileBuf[1] = uint8_t(height);
+ fileBuf[2] = uint8_t(mozilla::gfx::SurfaceFormat::B8G8R8A8);
+
+ // Clear all bits to ensure in nsIconDecoder we assume we are already color
+ // managed and premultiplied.
+ fileBuf[3] = 0;
+
+ uint8_t* imageBuf = &fileBuf[4];
+
+ // Create a CGBitmapContext around imageBuf and draw iconImage to it.
+ // This gives us the image data in the format we want: BGRA, four bytes per
+ // pixel, in host endianness, with premultiplied alpha.
+ CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
+ CGContextRef ctx =
+ CGBitmapContextCreate(imageBuf, width, height, 8 /* bitsPerComponent */, width * 4, cs,
+ kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
+ CGColorSpaceRelease(cs);
+
+ NSGraphicsContext* oldContext = [NSGraphicsContext currentContext];
+ [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithCGContext:ctx
+ flipped:NO]];
+
+ [iconImage drawInRect:NSMakeRect(0, 0, width, height)];
+
+ [NSGraphicsContext setCurrentContext:oldContext];
+
+ CGContextRelease(ctx);
+
+ // Now, create a pipe and stuff our data into it
+ nsCOMPtr<nsIInputStream> inStream;
+ nsCOMPtr<nsIOutputStream> outStream;
+ NS_NewPipe(getter_AddRefs(inStream), getter_AddRefs(outStream), bufferCapacity, bufferCapacity,
+ aNonBlocking);
+
+ uint32_t written;
+ rv = outStream->Write((char*)fileBuf.get(), bufferCapacity, &written);
+ if (NS_SUCCEEDED(rv)) {
+ NS_IF_ADDREF(*_retval = inStream);
+ }
+
+ // Drop notification callbacks to prevent cycles.
+ mCallbacks = nullptr;
+
+ return NS_OK;
+
+ NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetLoadFlags(uint32_t* aLoadAttributes) {
+ return mPump->GetLoadFlags(aLoadAttributes);
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetLoadFlags(uint32_t aLoadAttributes) {
+ return mPump->SetLoadFlags(aLoadAttributes);
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { return GetTRRModeImpl(aTRRMode); }
+
+NS_IMETHODIMP
+nsIconChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { return SetTRRModeImpl(aTRRMode); }
+
+NS_IMETHODIMP
+nsIconChannel::GetIsDocument(bool* aIsDocument) {
+ return NS_GetIsDocumentChannel(this, aIsDocument);
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetContentType(nsACString& aContentType) {
+ aContentType.AssignLiteral(IMAGE_ICON_MS);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetContentType(const nsACString& aContentType) {
+ // It doesn't make sense to set the content-type on this type
+ // of channel...
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetContentCharset(nsACString& aContentCharset) {
+ aContentCharset.AssignLiteral(IMAGE_ICON_MS);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetContentCharset(const nsACString& aContentCharset) {
+ // It doesn't make sense to set the content-type on this type
+ // of channel...
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetContentDisposition(uint32_t* aContentDisposition) {
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetContentDisposition(uint32_t aContentDisposition) {
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetContentDispositionFilename(nsAString& aContentDispositionFilename) {
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetContentDispositionFilename(const nsAString& aContentDispositionFilename) {
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetContentDispositionHeader(nsACString& aContentDispositionHeader) {
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetContentLength(int64_t* aContentLength) {
+ *aContentLength = 0;
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetContentLength(int64_t aContentLength) {
+ MOZ_ASSERT_UNREACHABLE("nsIconChannel::SetContentLength");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetLoadGroup(nsILoadGroup** aLoadGroup) {
+ *aLoadGroup = mLoadGroup;
+ NS_IF_ADDREF(*aLoadGroup);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) {
+ mLoadGroup = aLoadGroup;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetOwner(nsISupports** aOwner) {
+ *aOwner = mOwner.get();
+ NS_IF_ADDREF(*aOwner);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetOwner(nsISupports* aOwner) {
+ mOwner = aOwner;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetLoadInfo(nsILoadInfo** aLoadInfo) {
+ NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) {
+ MOZ_RELEASE_ASSERT(aLoadInfo, "loadinfo can't be null");
+ mLoadInfo = aLoadInfo;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetNotificationCallbacks(nsIInterfaceRequestor** aNotificationCallbacks) {
+ *aNotificationCallbacks = mCallbacks.get();
+ NS_IF_ADDREF(*aNotificationCallbacks);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks) {
+ mCallbacks = aNotificationCallbacks;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetSecurityInfo(nsITransportSecurityInfo** aSecurityInfo) {
+ *aSecurityInfo = nullptr;
+ return NS_OK;
+}
diff --git a/image/decoders/icon/moz.build b/image/decoders/icon/moz.build
new file mode 100644
index 0000000000..96cf951b3b
--- /dev/null
+++ b/image/decoders/icon/moz.build
@@ -0,0 +1,39 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+UNIFIED_SOURCES += [
+ "nsIconProtocolHandler.cpp",
+ "nsIconURI.cpp",
+]
+
+XPCOM_MANIFESTS += [
+ "components.conf",
+]
+
+FINAL_LIBRARY = "xul"
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+EXPORTS += [
+ "nsIconURI.h",
+]
+
+platform = None
+
+if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
+ platform = "gtk"
+
+if CONFIG["OS_ARCH"] == "WINNT":
+ platform = "win"
+
+if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
+ platform = "mac"
+
+if CONFIG["OS_TARGET"] == "Android":
+ platform = "android"
+
+if platform:
+ LOCAL_INCLUDES += [platform]
diff --git a/image/decoders/icon/nsIconProtocolHandler.cpp b/image/decoders/icon/nsIconProtocolHandler.cpp
new file mode 100644
index 0000000000..9334f908db
--- /dev/null
+++ b/image/decoders/icon/nsIconProtocolHandler.cpp
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIconProtocolHandler.h"
+
+#include "nsIconChannel.h"
+#include "nsIconURI.h"
+#include "nsCRT.h"
+#include "nsCOMPtr.h"
+#include "nsNetCID.h"
+
+///////////////////////////////////////////////////////////////////////////////
+
+nsIconProtocolHandler::nsIconProtocolHandler() {}
+
+nsIconProtocolHandler::~nsIconProtocolHandler() {}
+
+NS_IMPL_ISUPPORTS(nsIconProtocolHandler, nsIProtocolHandler,
+ nsISupportsWeakReference)
+
+///////////////////////////////////////////////////////////////////////////////
+// nsIProtocolHandler methods:
+
+NS_IMETHODIMP
+nsIconProtocolHandler::GetScheme(nsACString& result) {
+ result = "moz-icon";
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconProtocolHandler::AllowPort(int32_t port, const char* scheme,
+ bool* _retval) {
+ // don't override anything.
+ *_retval = false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconProtocolHandler::NewChannel(nsIURI* url, nsILoadInfo* aLoadInfo,
+ nsIChannel** result) {
+ NS_ENSURE_ARG_POINTER(url);
+ nsIconChannel* channel = new nsIconChannel;
+ if (!channel) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ NS_ADDREF(channel);
+
+ nsresult rv = channel->Init(url);
+ if (NS_FAILED(rv)) {
+ NS_RELEASE(channel);
+ return rv;
+ }
+
+ // set the loadInfo on the new channel
+ rv = channel->SetLoadInfo(aLoadInfo);
+ if (NS_FAILED(rv)) {
+ NS_RELEASE(channel);
+ return rv;
+ }
+
+ *result = channel;
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
diff --git a/image/decoders/icon/nsIconProtocolHandler.h b/image/decoders/icon/nsIconProtocolHandler.h
new file mode 100644
index 0000000000..63843eaa4b
--- /dev/null
+++ b/image/decoders/icon/nsIconProtocolHandler.h
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_icon_nsIconProtocolHandler_h
+#define mozilla_image_decoders_icon_nsIconProtocolHandler_h
+
+#include "nsWeakReference.h"
+#include "nsIProtocolHandler.h"
+
+class nsIconProtocolHandler : public nsIProtocolHandler,
+ public nsSupportsWeakReference {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPROTOCOLHANDLER
+
+ // nsIconProtocolHandler methods:
+ nsIconProtocolHandler();
+
+ protected:
+ virtual ~nsIconProtocolHandler();
+};
+
+#endif // mozilla_image_decoders_icon_nsIconProtocolHandler_h
diff --git a/image/decoders/icon/nsIconURI.cpp b/image/decoders/icon/nsIconURI.cpp
new file mode 100644
index 0000000000..d917337bf9
--- /dev/null
+++ b/image/decoders/icon/nsIconURI.cpp
@@ -0,0 +1,654 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set sw=2 sts=2 ts=2 et tw=80:
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIconURI.h"
+
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/ipc/URIUtils.h"
+#include "mozilla/Sprintf.h"
+
+#include "nsIClassInfoImpl.h"
+#include "nsIIOService.h"
+#include "nsISerializable.h"
+#include "nsIObjectInputStream.h"
+#include "nsIObjectOutputStream.h"
+#include "nsIURL.h"
+#include "nsNetUtil.h"
+#include "plstr.h"
+#include "nsCRT.h"
+#include <stdlib.h>
+
+using namespace mozilla;
+using namespace mozilla::ipc;
+
+#define DEFAULT_IMAGE_SIZE 16
+
+#if defined(MAX_PATH)
+# define SANE_FILE_NAME_LEN MAX_PATH
+#elif defined(PATH_MAX)
+# define SANE_FILE_NAME_LEN PATH_MAX
+#else
+# define SANE_FILE_NAME_LEN 1024
+#endif
+
+static NS_DEFINE_CID(kThisIconURIImplementationCID,
+ NS_THIS_ICONURI_IMPLEMENTATION_CID);
+
+static const char* const kSizeStrings[] = {"button", "toolbar", "toolbarsmall",
+ "menu", "dnd", "dialog"};
+
+static const char* const kStateStrings[] = {"normal", "disabled"};
+
+////////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_CLASSINFO(nsMozIconURI, nullptr, nsIClassInfo::THREADSAFE,
+ NS_ICONURI_CID)
+// Empty CI getter. We only need nsIClassInfo for Serialization
+NS_IMPL_CI_INTERFACE_GETTER0(nsMozIconURI)
+
+nsMozIconURI::nsMozIconURI()
+ : mSize(DEFAULT_IMAGE_SIZE), mIconSize(-1), mIconState(-1) {}
+
+nsMozIconURI::~nsMozIconURI() {}
+
+NS_IMPL_ADDREF(nsMozIconURI)
+NS_IMPL_RELEASE(nsMozIconURI)
+
+NS_INTERFACE_MAP_BEGIN(nsMozIconURI)
+ if (aIID.Equals(kThisIconURIImplementationCID)) {
+ foundInterface = static_cast<nsIURI*>(this);
+ } else
+ NS_INTERFACE_MAP_ENTRY(nsIMozIconURI)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURI)
+ NS_INTERFACE_MAP_ENTRY(nsIURI)
+ NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsINestedURI, mIconURL)
+ NS_INTERFACE_MAP_ENTRY(nsISerializable)
+ NS_IMPL_QUERY_CLASSINFO(nsMozIconURI)
+NS_INTERFACE_MAP_END
+
+#define MOZICON_SCHEME "moz-icon:"
+#define MOZICON_SCHEME_LEN (sizeof(MOZICON_SCHEME) - 1)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIURI methods:
+
+NS_IMETHODIMP
+nsMozIconURI::GetSpec(nsACString& aSpec) {
+ aSpec = MOZICON_SCHEME;
+
+ if (mIconURL) {
+ nsAutoCString fileIconSpec;
+ nsresult rv = mIconURL->GetSpec(fileIconSpec);
+ NS_ENSURE_SUCCESS(rv, rv);
+ aSpec += fileIconSpec;
+ } else if (!mStockIcon.IsEmpty()) {
+ aSpec += "//stock/";
+ aSpec += mStockIcon;
+ } else {
+ aSpec += "//";
+ aSpec += mFileName;
+ }
+
+ aSpec += "?size=";
+ if (mIconSize >= 0) {
+ aSpec += kSizeStrings[mIconSize];
+ } else {
+ char buf[20];
+ SprintfLiteral(buf, "%d", mSize);
+ aSpec.Append(buf);
+ }
+
+ if (mIconState >= 0) {
+ aSpec += "&state=";
+ aSpec += kStateStrings[mIconState];
+ }
+
+ if (!mContentType.IsEmpty()) {
+ aSpec += "&contentType=";
+ aSpec += mContentType.get();
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetSpecIgnoringRef(nsACString& result) { return GetSpec(result); }
+
+NS_IMETHODIMP
+nsMozIconURI::GetDisplaySpec(nsACString& aUnicodeSpec) {
+ return GetSpec(aUnicodeSpec);
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetDisplayHostPort(nsACString& aUnicodeHostPort) {
+ return GetHostPort(aUnicodeHostPort);
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetDisplayHost(nsACString& aUnicodeHost) {
+ return GetHost(aUnicodeHost);
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetDisplayPrePath(nsACString& aPrePath) {
+ return GetPrePath(aPrePath);
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetHasRef(bool* result) {
+ *result = false;
+ return NS_OK;
+}
+
+NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsMozIconURI::Mutator, nsIURISetters,
+ nsIURIMutator, nsISerializable)
+
+NS_IMETHODIMP
+nsMozIconURI::Mutate(nsIURIMutator** aMutator) {
+ RefPtr<nsMozIconURI::Mutator> mutator = new nsMozIconURI::Mutator();
+ nsresult rv = mutator->InitFromURI(this);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ mutator.forget(aMutator);
+ return NS_OK;
+}
+
+// helper function for parsing out attributes like size, and contentType
+// from the icon url.
+// takes a string like ?size=32&contentType=text/html and returns a new string
+// containing just the attribute value. i.e you could pass in this string with
+// an attribute name of 'size=', this will return 32
+// Assumption: attribute pairs in the string are separated by '&'.
+static void extractAttributeValue(const char* aSearchString,
+ const char* aAttributeName,
+ nsCString& aResult) {
+ aResult.Truncate();
+
+ if (aSearchString && aAttributeName) {
+ // search the string for attributeName
+ uint32_t attributeNameSize = strlen(aAttributeName);
+ const char* startOfAttribute = PL_strcasestr(aSearchString, aAttributeName);
+ if (startOfAttribute &&
+ (*(startOfAttribute - 1) == '?' || *(startOfAttribute - 1) == '&')) {
+ startOfAttribute += attributeNameSize; // skip over the attributeName
+ // is there something after the attribute name
+ if (*startOfAttribute) {
+ const char* endofAttribute = strchr(startOfAttribute, '&');
+ if (endofAttribute) {
+ aResult.Assign(Substring(startOfAttribute, endofAttribute));
+ } else {
+ aResult.Assign(startOfAttribute);
+ }
+ } // if we have a attribute value
+ } // if we have a attribute name
+ } // if we got non-null search string and attribute name values
+}
+
+nsresult nsMozIconURI::SetSpecInternal(const nsACString& aSpec) {
+ // Reset everything to default values.
+ mIconURL = nullptr;
+ mSize = DEFAULT_IMAGE_SIZE;
+ mContentType.Truncate();
+ mFileName.Truncate();
+ mStockIcon.Truncate();
+ mIconSize = -1;
+ mIconState = -1;
+
+ nsAutoCString iconSpec(aSpec);
+ if (!Substring(iconSpec, 0, MOZICON_SCHEME_LEN)
+ .EqualsLiteral(MOZICON_SCHEME) ||
+ (!Substring(iconSpec, MOZICON_SCHEME_LEN, 7).EqualsLiteral("file://") &&
+ // Checking for the leading '//' will match both the '//stock/' and
+ // '//.foo' cases:
+ !Substring(iconSpec, MOZICON_SCHEME_LEN, 2).EqualsLiteral("//"))) {
+ return NS_ERROR_MALFORMED_URI;
+ }
+
+ int32_t questionMarkPos = iconSpec.Find("?");
+ if (questionMarkPos != -1 &&
+ static_cast<int32_t>(iconSpec.Length()) > (questionMarkPos + 1)) {
+ extractAttributeValue(iconSpec.get(), "contentType=", mContentType);
+
+ nsAutoCString sizeString;
+ extractAttributeValue(iconSpec.get(), "size=", sizeString);
+ if (!sizeString.IsEmpty()) {
+ const char* sizeStr = sizeString.get();
+ for (uint32_t i = 0; i < ArrayLength(kSizeStrings); i++) {
+ if (nsCRT::strcasecmp(sizeStr, kSizeStrings[i]) == 0) {
+ mIconSize = i;
+ break;
+ }
+ }
+
+ int32_t sizeValue = atoi(sizeString.get());
+ if (sizeValue > 0) {
+ mSize = sizeValue;
+ }
+ }
+
+ nsAutoCString stateString;
+ extractAttributeValue(iconSpec.get(), "state=", stateString);
+ if (!stateString.IsEmpty()) {
+ const char* stateStr = stateString.get();
+ for (uint32_t i = 0; i < ArrayLength(kStateStrings); i++) {
+ if (nsCRT::strcasecmp(stateStr, kStateStrings[i]) == 0) {
+ mIconState = i;
+ break;
+ }
+ }
+ }
+ }
+
+ int32_t pathLength = iconSpec.Length() - MOZICON_SCHEME_LEN;
+ if (questionMarkPos != -1) {
+ pathLength = questionMarkPos - MOZICON_SCHEME_LEN;
+ }
+ if (pathLength < 3) {
+ return NS_ERROR_MALFORMED_URI;
+ }
+
+ nsAutoCString iconPath(Substring(iconSpec, MOZICON_SCHEME_LEN, pathLength));
+
+ // Icon URI path can have three forms:
+ // (1) //stock/<icon-identifier>
+ // (2) //<some dummy file with an extension>
+ // (3) a valid URL
+
+ if (!strncmp("//stock/", iconPath.get(), 8)) {
+ mStockIcon.Assign(Substring(iconPath, 8));
+ // An icon identifier must always be specified.
+ if (mStockIcon.IsEmpty()) {
+ return NS_ERROR_MALFORMED_URI;
+ }
+ return NS_OK;
+ }
+
+ if (StringBeginsWith(iconPath, "//"_ns)) {
+ // Sanity check this supposed dummy file name.
+ if (iconPath.Length() > SANE_FILE_NAME_LEN) {
+ return NS_ERROR_MALFORMED_URI;
+ }
+ iconPath.Cut(0, 2);
+ mFileName.Assign(iconPath);
+ }
+
+ nsresult rv;
+ nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIURI> uri;
+ ioService->NewURI(iconPath, nullptr, nullptr, getter_AddRefs(uri));
+ mIconURL = do_QueryInterface(uri);
+ if (mIconURL) {
+ // The inner URI should be a 'file:' one. If not, bail.
+ if (!mIconURL->SchemeIs("file")) {
+ return NS_ERROR_MALFORMED_URI;
+ }
+ mFileName.Truncate();
+ } else if (mFileName.IsEmpty()) {
+ return NS_ERROR_MALFORMED_URI;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetPrePath(nsACString& prePath) {
+ prePath = MOZICON_SCHEME;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetScheme(nsACString& aScheme) {
+ aScheme = "moz-icon";
+ return NS_OK;
+}
+
+nsresult nsMozIconURI::SetScheme(const nsACString& aScheme) {
+ // doesn't make sense to set the scheme of a moz-icon URL
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetUsername(nsACString& aUsername) { return NS_ERROR_FAILURE; }
+
+nsresult nsMozIconURI::SetUsername(const nsACString& aUsername) {
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetPassword(nsACString& aPassword) { return NS_ERROR_FAILURE; }
+
+nsresult nsMozIconURI::SetPassword(const nsACString& aPassword) {
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetUserPass(nsACString& aUserPass) { return NS_ERROR_FAILURE; }
+
+nsresult nsMozIconURI::SetUserPass(const nsACString& aUserPass) {
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetHostPort(nsACString& aHostPort) { return NS_ERROR_FAILURE; }
+
+nsresult nsMozIconURI::SetHostPort(const nsACString& aHostPort) {
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetHost(nsACString& aHost) { return NS_ERROR_FAILURE; }
+
+nsresult nsMozIconURI::SetHost(const nsACString& aHost) {
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetPort(int32_t* aPort) { return NS_ERROR_FAILURE; }
+
+nsresult nsMozIconURI::SetPort(int32_t aPort) { return NS_ERROR_FAILURE; }
+
+NS_IMETHODIMP
+nsMozIconURI::GetPathQueryRef(nsACString& aPath) {
+ aPath.Truncate();
+ return NS_OK;
+}
+
+nsresult nsMozIconURI::SetPathQueryRef(const nsACString& aPath) {
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetFilePath(nsACString& aFilePath) {
+ aFilePath.Truncate();
+ return NS_OK;
+}
+
+nsresult nsMozIconURI::SetFilePath(const nsACString& aFilePath) {
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetQuery(nsACString& aQuery) {
+ aQuery.Truncate();
+ return NS_OK;
+}
+
+nsresult nsMozIconURI::SetQuery(const nsACString& aQuery) {
+ return NS_ERROR_FAILURE;
+}
+
+nsresult nsMozIconURI::SetQueryWithEncoding(const nsACString& aQuery,
+ const Encoding* aEncoding) {
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetRef(nsACString& aRef) {
+ aRef.Truncate();
+ return NS_OK;
+}
+
+nsresult nsMozIconURI::SetRef(const nsACString& aRef) {
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::Equals(nsIURI* other, bool* result) {
+ *result = false;
+ NS_ENSURE_ARG_POINTER(other);
+ MOZ_ASSERT(result, "null pointer");
+
+ nsAutoCString spec1;
+ nsAutoCString spec2;
+
+ nsresult rv = GetSpec(spec1);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = other->GetSpec(spec2);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (!nsCRT::strcasecmp(spec1.get(), spec2.get())) {
+ *result = true;
+ } else {
+ *result = false;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::EqualsExceptRef(nsIURI* other, bool* result) {
+ // GetRef/SetRef not supported by nsMozIconURI, so
+ // EqualsExceptRef() is the same as Equals().
+ return Equals(other, result);
+}
+
+NS_IMETHODIMP
+nsMozIconURI::SchemeIs(const char* aScheme, bool* aEquals) {
+ MOZ_ASSERT(aEquals, "null pointer");
+ if (!aScheme) {
+ *aEquals = false;
+ return NS_OK;
+ }
+
+ *aEquals = nsCRT::strcasecmp("moz-icon", aScheme) == 0;
+ return NS_OK;
+}
+
+nsresult nsMozIconURI::Clone(nsIURI** result) {
+ nsCOMPtr<nsIURL> newIconURL;
+ if (mIconURL) {
+ newIconURL = mIconURL;
+ }
+
+ RefPtr<nsMozIconURI> uri = new nsMozIconURI();
+ newIconURL.swap(uri->mIconURL);
+ uri->mSize = mSize;
+ uri->mContentType = mContentType;
+ uri->mFileName = mFileName;
+ uri->mStockIcon = mStockIcon;
+ uri->mIconSize = mIconSize;
+ uri->mIconState = mIconState;
+ uri.forget(result);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::Resolve(const nsACString& relativePath, nsACString& result) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetAsciiSpec(nsACString& aSpecA) { return GetSpec(aSpecA); }
+
+NS_IMETHODIMP
+nsMozIconURI::GetAsciiHostPort(nsACString& aHostPortA) {
+ return GetHostPort(aHostPortA);
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetAsciiHost(nsACString& aHostA) { return GetHost(aHostA); }
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIIconUri methods:
+
+NS_IMETHODIMP
+nsMozIconURI::GetIconURL(nsIURL** aFileUrl) {
+ *aFileUrl = mIconURL;
+ NS_IF_ADDREF(*aFileUrl);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetImageSize(uint32_t* aImageSize)
+// measured by # of pixels in a row. defaults to 16.
+{
+ *aImageSize = mSize;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetContentType(nsACString& aContentType) {
+ aContentType = mContentType;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetFileExtension(nsACString& aFileExtension) {
+ // First, try to get the extension from mIconURL if we have one
+ if (mIconURL) {
+ nsAutoCString fileExt;
+ if (NS_SUCCEEDED(mIconURL->GetFileExtension(fileExt))) {
+ if (!fileExt.IsEmpty()) {
+ // unfortunately, this code doesn't give us the required '.' in
+ // front of the extension so we have to do it ourselves.
+ aFileExtension.Assign('.');
+ aFileExtension.Append(fileExt);
+ }
+ }
+ return NS_OK;
+ }
+
+ if (!mFileName.IsEmpty()) {
+ // truncate the extension out of the file path...
+ const char* chFileName = mFileName.get(); // get the underlying buffer
+ const char* fileExt = strrchr(chFileName, '.');
+ if (!fileExt) {
+ return NS_OK;
+ }
+ aFileExtension = fileExt;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetStockIcon(nsACString& aStockIcon) {
+ aStockIcon = mStockIcon;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetIconSize(nsACString& aSize) {
+ if (mIconSize >= 0) {
+ aSize = kSizeStrings[mIconSize];
+ } else {
+ aSize.Truncate();
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetIconState(nsACString& aState) {
+ if (mIconState >= 0) {
+ aState = kStateStrings[mIconState];
+ } else {
+ aState.Truncate();
+ }
+ return NS_OK;
+}
+
+void nsMozIconURI::Serialize(URIParams& aParams) {
+ IconURIParams params;
+
+ if (mIconURL) {
+ URIParams iconURLParams;
+ SerializeURI(mIconURL, iconURLParams);
+ if (iconURLParams.type() == URIParams::T__None) {
+ // Serialization failed, bail.
+ return;
+ }
+
+ params.uri() = Some(std::move(iconURLParams));
+ } else {
+ params.uri() = Nothing();
+ }
+
+ params.size() = mSize;
+ params.fileName() = mFileName;
+ params.stockIcon() = mStockIcon;
+ params.iconSize() = mIconSize;
+ params.iconState() = mIconState;
+
+ aParams = params;
+}
+
+bool nsMozIconURI::Deserialize(const URIParams& aParams) {
+ if (aParams.type() != URIParams::TIconURIParams) {
+ MOZ_ASSERT_UNREACHABLE("Received unknown URI from other process!");
+ return false;
+ }
+
+ const IconURIParams& params = aParams.get_IconURIParams();
+ if (params.uri().isSome()) {
+ nsCOMPtr<nsIURI> uri = DeserializeURI(params.uri().ref());
+ mIconURL = do_QueryInterface(uri);
+ if (!mIconURL) {
+ MOZ_ASSERT_UNREACHABLE("bad nsIURI passed");
+ return false;
+ }
+ }
+
+ mSize = params.size();
+ mContentType = params.contentType();
+ mFileName = params.fileName();
+ mStockIcon = params.stockIcon();
+
+ if (params.iconSize() < -1 ||
+ params.iconSize() >= (int32_t)ArrayLength(kSizeStrings)) {
+ return false;
+ }
+ mIconSize = params.iconSize();
+
+ if (params.iconState() < -1 ||
+ params.iconState() >= (int32_t)ArrayLength(kStateStrings)) {
+ return false;
+ }
+ mIconState = params.iconState();
+
+ return true;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetInnerURI(nsIURI** aURI) {
+ nsCOMPtr<nsIURI> iconURL = mIconURL;
+ if (!iconURL) {
+ *aURI = nullptr;
+ return NS_ERROR_FAILURE;
+ }
+
+ iconURL.forget(aURI);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetInnermostURI(nsIURI** aURI) {
+ return NS_ImplGetInnermostURI(this, aURI);
+}
+
+NS_IMETHODIMP
+nsMozIconURI::Read(nsIObjectInputStream* aStream) {
+ MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+nsresult nsMozIconURI::ReadPrivate(nsIObjectInputStream* aStream) {
+ nsAutoCString spec;
+ nsresult rv = aStream->ReadCString(spec);
+ NS_ENSURE_SUCCESS(rv, rv);
+ return SetSpecInternal(spec);
+}
+
+NS_IMETHODIMP
+nsMozIconURI::Write(nsIObjectOutputStream* aStream) {
+ nsAutoCString spec;
+ nsresult rv = GetSpec(spec);
+ NS_ENSURE_SUCCESS(rv, rv);
+ return aStream->WriteStringZ(spec.get());
+}
diff --git a/image/decoders/icon/nsIconURI.h b/image/decoders/icon/nsIconURI.h
new file mode 100644
index 0000000000..1f55bc686c
--- /dev/null
+++ b/image/decoders/icon/nsIconURI.h
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_icon_nsIconURI_h
+#define mozilla_image_decoders_icon_nsIconURI_h
+
+#include "nsIIconURI.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "nsINestedURI.h"
+#include "nsIURIMutator.h"
+#include "nsISerializable.h"
+
+#define NS_THIS_ICONURI_IMPLEMENTATION_CID \
+ { /* 0b9bb0c2-fee6-470b-b9b9-9fd9462b5e19 */ \
+ 0x5c3e417f, 0xb686, 0x4105, { \
+ 0x86, 0xe7, 0xf9, 0x1b, 0xac, 0x97, 0x4d, 0x5c \
+ } \
+ }
+
+namespace mozilla {
+class Encoding;
+}
+
+class nsMozIconURI final : public nsIMozIconURI,
+ public nsINestedURI,
+ public nsISerializable {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIURI
+ NS_DECL_NSIMOZICONURI
+ NS_DECL_NSINESTEDURI
+ NS_DECL_NSISERIALIZABLE
+
+ protected:
+ nsMozIconURI();
+ virtual ~nsMozIconURI();
+ nsCOMPtr<nsIURL> mIconURL; // a URL that we want the icon for
+ uint32_t mSize; // the # of pixels in a row that we want for this image.
+ // Typically 16, 32, 128, etc.
+ nsCString mContentType; // optional field explicitly specifying the content
+ // type
+ nsCString mFileName; // for if we don't have an actual file path, we're just
+ // given a filename with an extension
+ nsCString mStockIcon;
+ int32_t mIconSize; // -1 if not specified, otherwise index into
+ // kSizeStrings
+ int32_t mIconState; // -1 if not specified, otherwise index into
+ // kStateStrings
+
+ private:
+ nsresult Clone(nsIURI** aURI);
+ nsresult SetSpecInternal(const nsACString& input);
+ nsresult SetScheme(const nsACString& input);
+ nsresult SetUserPass(const nsACString& input);
+ nsresult SetUsername(const nsACString& input);
+ nsresult SetPassword(const nsACString& input);
+ nsresult SetHostPort(const nsACString& aValue);
+ nsresult SetHost(const nsACString& input);
+ nsresult SetPort(int32_t port);
+ nsresult SetPathQueryRef(const nsACString& input);
+ nsresult SetRef(const nsACString& input);
+ nsresult SetFilePath(const nsACString& input);
+ nsresult SetQuery(const nsACString& input);
+ nsresult SetQueryWithEncoding(const nsACString& input,
+ const mozilla::Encoding* encoding);
+ nsresult ReadPrivate(nsIObjectInputStream* stream);
+ bool Deserialize(const mozilla::ipc::URIParams&);
+
+ public:
+ class Mutator final : public nsIURIMutator,
+ public BaseURIMutator<nsMozIconURI>,
+ public nsISerializable {
+ NS_DECL_ISUPPORTS
+ NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
+
+ NS_IMETHOD
+ Write(nsIObjectOutputStream* aOutputStream) override {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+
+ [[nodiscard]] NS_IMETHOD Read(nsIObjectInputStream* aStream) override {
+ return InitFromInputStream(aStream);
+ }
+
+ NS_IMETHOD Deserialize(const mozilla::ipc::URIParams& aParams) override {
+ return InitFromIPCParams(aParams);
+ }
+
+ NS_IMETHOD Finalize(nsIURI** aURI) override {
+ mURI.forget(aURI);
+ return NS_OK;
+ }
+
+ NS_IMETHOD SetSpec(const nsACString& aSpec,
+ nsIURIMutator** aMutator) override {
+ if (aMutator) {
+ nsCOMPtr<nsIURIMutator> mutator = this;
+ mutator.forget(aMutator);
+ }
+ return InitFromSpec(aSpec);
+ }
+
+ explicit Mutator() {}
+
+ private:
+ virtual ~Mutator() {}
+
+ friend class nsMozIconURI;
+ };
+
+ friend BaseURIMutator<nsMozIconURI>;
+};
+
+#endif // mozilla_image_decoders_icon_nsIconURI_h
diff --git a/image/decoders/icon/win/moz.build b/image/decoders/icon/win/moz.build
new file mode 100644
index 0000000000..c4472f89ac
--- /dev/null
+++ b/image/decoders/icon/win/moz.build
@@ -0,0 +1,21 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+SOURCES += [
+ "nsIconChannel.cpp",
+]
+
+EXPORTS += [
+ "nsIconChannel.h",
+]
+
+LOCAL_INCLUDES += [
+ "/image",
+]
+
+FINAL_LIBRARY = "xul"
+
+include("/ipc/chromium/chromium-config.mozbuild")
diff --git a/image/decoders/icon/win/nsIconChannel.cpp b/image/decoders/icon/win/nsIconChannel.cpp
new file mode 100644
index 0000000000..fe76afe9b1
--- /dev/null
+++ b/image/decoders/icon/win/nsIconChannel.cpp
@@ -0,0 +1,1006 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/BasePrincipal.h"
+#include "mozilla/Monitor.h"
+#include "mozilla/SyncRunnable.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/UniquePtrExtensions.h"
+#include "mozilla/WindowsProcessMitigations.h"
+#include "mozilla/dom/ContentChild.h"
+#include "mozilla/ipc/ByteBuf.h"
+
+#include "nsComponentManagerUtils.h"
+#include "nsIconChannel.h"
+#include "nsIIconURI.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsString.h"
+#include "nsReadableUtils.h"
+#include "nsMimeTypes.h"
+#include "nsIURL.h"
+#include "nsIPipe.h"
+#include "nsNetCID.h"
+#include "nsIFile.h"
+#include "nsIFileURL.h"
+#include "nsIIconURI.h"
+#include "nsIAsyncInputStream.h"
+#include "nsIAsyncOutputStream.h"
+#include "nsIMIMEService.h"
+#include "nsCExternalHandlerService.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsProxyRelease.h"
+#include "nsContentSecurityManager.h"
+#include "nsContentUtils.h"
+#include "nsNetUtil.h"
+#include "nsThreadUtils.h"
+
+#include "Decoder.h"
+#include "DecodePool.h"
+
+// we need windows.h to read out registry information...
+#include <windows.h>
+#include <shellapi.h>
+#include <shlobj.h>
+#include <objbase.h>
+#include <wchar.h>
+
+using namespace mozilla;
+using namespace mozilla::image;
+
+using mozilla::ipc::ByteBuf;
+
+struct ICONFILEHEADER {
+ uint16_t ifhReserved;
+ uint16_t ifhType;
+ uint16_t ifhCount;
+};
+
+struct ICONENTRY {
+ int8_t ieWidth;
+ int8_t ieHeight;
+ uint8_t ieColors;
+ uint8_t ieReserved;
+ uint16_t iePlanes;
+ uint16_t ieBitCount;
+ uint32_t ieSizeImage;
+ uint32_t ieFileOffset;
+};
+
+struct IconPathInfo {
+ nsCOMPtr<nsIFile> localFile;
+ nsAutoString filePath;
+ UINT infoFlags = 0;
+};
+
+using HIconPromise = MozPromise<HICON, nsresult, true>;
+
+static UINT GetSizeInfoFlag(uint32_t aDesiredImageSize) {
+ return aDesiredImageSize > 16 ? SHGFI_SHELLICONSIZE : SHGFI_SMALLICON;
+}
+
+static nsresult ExtractIconInfoFromUrl(nsIURI* aUrl, nsIFile** aLocalFile,
+ uint32_t* aDesiredImageSize,
+ nsCString& aContentType,
+ nsCString& aFileExtension) {
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIMozIconURI> iconURI(do_QueryInterface(aUrl, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ iconURI->GetImageSize(aDesiredImageSize);
+ iconURI->GetContentType(aContentType);
+ iconURI->GetFileExtension(aFileExtension);
+
+ nsCOMPtr<nsIURL> url;
+ rv = iconURI->GetIconURL(getter_AddRefs(url));
+ if (NS_FAILED(rv) || !url) return NS_OK;
+
+ nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(url, &rv);
+ if (NS_FAILED(rv) || !fileURL) return NS_OK;
+
+ nsCOMPtr<nsIFile> file;
+ rv = fileURL->GetFile(getter_AddRefs(file));
+ if (NS_FAILED(rv) || !file) return NS_OK;
+
+ return file->Clone(aLocalFile);
+}
+
+static nsresult ExtractIconPathInfoFromUrl(nsIURI* aUrl,
+ IconPathInfo* aIconPathInfo) {
+ nsCString contentType;
+ nsCString fileExt;
+ nsCOMPtr<nsIFile> localFile; // file we want an icon for
+ uint32_t desiredImageSize;
+ nsresult rv = ExtractIconInfoFromUrl(aUrl, getter_AddRefs(localFile),
+ &desiredImageSize, contentType, fileExt);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // if the file exists, we are going to use it's real attributes...
+ // otherwise we only want to use it for it's extension...
+ UINT infoFlags = SHGFI_ICON;
+
+ bool fileExists = false;
+
+ nsAutoString filePath;
+ CopyASCIItoUTF16(fileExt, filePath);
+ if (localFile) {
+ rv = localFile->Normalize();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ localFile->GetPath(filePath);
+ if (filePath.Length() < 2 || filePath[1] != ':') {
+ return NS_ERROR_MALFORMED_URI; // UNC
+ }
+
+ if (filePath.Last() == ':') {
+ filePath.Append('\\');
+ } else {
+ localFile->Exists(&fileExists);
+ if (!fileExists) {
+ localFile->GetLeafName(filePath);
+ }
+ }
+ }
+
+ if (!fileExists) {
+ infoFlags |= SHGFI_USEFILEATTRIBUTES;
+ }
+
+ infoFlags |= GetSizeInfoFlag(desiredImageSize);
+
+ // if we have a content type... then use it! but for existing files,
+ // we want to show their real icon.
+ if (!fileExists && !contentType.IsEmpty()) {
+ nsCOMPtr<nsIMIMEService> mimeService(
+ do_GetService(NS_MIMESERVICE_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsAutoCString defFileExt;
+ mimeService->GetPrimaryExtension(contentType, fileExt, defFileExt);
+ // If the mime service does not know about this mime type, we show
+ // the generic icon.
+ // In any case, we need to insert a '.' before the extension.
+ filePath = u"."_ns + NS_ConvertUTF8toUTF16(defFileExt);
+ }
+
+ if (!localFile && !fileExists &&
+ ((filePath.Length() == 1 && filePath.Last() == '.') ||
+ filePath.Length() == 0)) {
+ filePath = u".MozBogusExtensionMoz"_ns;
+ }
+
+ aIconPathInfo->localFile = std::move(localFile);
+ aIconPathInfo->filePath = std::move(filePath);
+ aIconPathInfo->infoFlags = infoFlags;
+
+ return NS_OK;
+}
+
+static bool GetSpecialFolderIcon(nsIFile* aFile, int aFolder, UINT aInfoFlags,
+ HICON* aIcon) {
+ if (!aFile) {
+ return false;
+ }
+
+ wchar_t fileNativePath[MAX_PATH];
+ nsAutoString fileNativePathStr;
+ aFile->GetPath(fileNativePathStr);
+ ::GetShortPathNameW(fileNativePathStr.get(), fileNativePath,
+ ArrayLength(fileNativePath));
+
+ struct IdListDeleter {
+ void operator()(ITEMIDLIST* ptr) { ::CoTaskMemFree(ptr); }
+ };
+
+ UniquePtr<ITEMIDLIST, IdListDeleter> idList;
+ HRESULT hr =
+ ::SHGetSpecialFolderLocation(nullptr, aFolder, getter_Transfers(idList));
+ if (FAILED(hr)) {
+ return false;
+ }
+
+ wchar_t specialNativePath[MAX_PATH];
+ ::SHGetPathFromIDListW(idList.get(), specialNativePath);
+ ::GetShortPathNameW(specialNativePath, specialNativePath,
+ ArrayLength(specialNativePath));
+
+ if (wcsicmp(fileNativePath, specialNativePath) != 0) {
+ return false;
+ }
+
+ SHFILEINFOW sfi = {};
+ aInfoFlags |= (SHGFI_PIDL | SHGFI_SYSICONINDEX);
+ if (::SHGetFileInfoW((LPCWSTR)(LPCITEMIDLIST)idList.get(), 0, &sfi,
+ sizeof(sfi), aInfoFlags) == 0) {
+ return false;
+ }
+
+ *aIcon = sfi.hIcon;
+ return true;
+}
+
+static nsresult GetIconHandleFromPathInfo(const IconPathInfo& aPathInfo,
+ HICON* aIcon) {
+ MOZ_DIAGNOSTIC_ASSERT(!IsWin32kLockedDown());
+
+ // Is this the "Desktop" folder?
+ if (GetSpecialFolderIcon(aPathInfo.localFile, CSIDL_DESKTOP,
+ aPathInfo.infoFlags, aIcon)) {
+ return NS_OK;
+ }
+
+ // Is this the "My Documents" folder?
+ if (GetSpecialFolderIcon(aPathInfo.localFile, CSIDL_PERSONAL,
+ aPathInfo.infoFlags, aIcon)) {
+ return NS_OK;
+ }
+
+ // There are other "Special Folders" and Namespace entities that we
+ // are not fetching icons for, see:
+ // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/
+ // shellcc/platform/shell/reference/enums/csidl.asp
+ // If we ever need to get them, code to do so would be inserted here.
+
+ // Not a special folder, or something else failed above.
+ SHFILEINFOW sfi = {};
+ if (::SHGetFileInfoW(aPathInfo.filePath.get(), FILE_ATTRIBUTE_ARCHIVE, &sfi,
+ sizeof(sfi), aPathInfo.infoFlags) != 0) {
+ *aIcon = sfi.hIcon;
+ return NS_OK;
+ }
+
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+// Match stock icons with names
+static mozilla::Maybe<SHSTOCKICONID> GetStockIconIDForName(
+ const nsACString& aStockName) {
+ return aStockName.EqualsLiteral("uac-shield") ? Some(SIID_SHIELD) : Nothing();
+}
+
+// Specific to Vista and above
+static nsresult GetStockHIcon(nsIMozIconURI* aIconURI, HICON* aIcon) {
+ uint32_t desiredImageSize;
+ aIconURI->GetImageSize(&desiredImageSize);
+ nsAutoCString stockIcon;
+ aIconURI->GetStockIcon(stockIcon);
+
+ Maybe<SHSTOCKICONID> stockIconID = GetStockIconIDForName(stockIcon);
+ if (stockIconID.isNothing()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ UINT infoFlags = SHGSI_ICON;
+ infoFlags |= GetSizeInfoFlag(desiredImageSize);
+
+ SHSTOCKICONINFO sii = {0};
+ sii.cbSize = sizeof(sii);
+ HRESULT hr = SHGetStockIconInfo(*stockIconID, infoFlags, &sii);
+ if (FAILED(hr)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ *aIcon = sii.hIcon;
+
+ return NS_OK;
+}
+
+// Given a BITMAPINFOHEADER, returns the size of the color table.
+static int GetColorTableSize(BITMAPINFOHEADER* aHeader) {
+ int colorTableSize = -1;
+
+ // http://msdn.microsoft.com/en-us/library/dd183376%28v=VS.85%29.aspx
+ switch (aHeader->biBitCount) {
+ case 0:
+ colorTableSize = 0;
+ break;
+ case 1:
+ colorTableSize = 2 * sizeof(RGBQUAD);
+ break;
+ case 4:
+ case 8: {
+ // The maximum possible size for the color table is 2**bpp, so check for
+ // that and fail if we're not in those bounds
+ unsigned int maxEntries = 1 << (aHeader->biBitCount);
+ if (aHeader->biClrUsed > 0 && aHeader->biClrUsed <= maxEntries) {
+ colorTableSize = aHeader->biClrUsed * sizeof(RGBQUAD);
+ } else if (aHeader->biClrUsed == 0) {
+ colorTableSize = maxEntries * sizeof(RGBQUAD);
+ }
+ break;
+ }
+ case 16:
+ case 32:
+ // If we have BI_BITFIELDS compression, we would normally need 3 DWORDS
+ // for the bitfields mask which would be stored in the color table;
+ // However, we instead force the bitmap to request data of type BI_RGB so
+ // the color table should be of size 0. Setting aHeader->biCompression =
+ // BI_RGB forces the later call to GetDIBits to return to us BI_RGB data.
+ if (aHeader->biCompression == BI_BITFIELDS) {
+ aHeader->biCompression = BI_RGB;
+ }
+ colorTableSize = 0;
+ break;
+ case 24:
+ colorTableSize = 0;
+ break;
+ }
+
+ if (colorTableSize < 0) {
+ NS_WARNING("Unable to figure out the color table size for this bitmap");
+ }
+
+ return colorTableSize;
+}
+
+// Given a header and a size, creates a freshly allocated BITMAPINFO structure.
+// It is the caller's responsibility to null-check and delete the structure.
+static BITMAPINFO* CreateBitmapInfo(BITMAPINFOHEADER* aHeader,
+ size_t aColorTableSize) {
+ BITMAPINFO* bmi = (BITMAPINFO*)::operator new(
+ sizeof(BITMAPINFOHEADER) + aColorTableSize, mozilla::fallible);
+ if (bmi) {
+ memcpy(bmi, aHeader, sizeof(BITMAPINFOHEADER));
+ memset(bmi->bmiColors, 0, aColorTableSize);
+ }
+ return bmi;
+}
+
+static nsresult MakeIconBuffer(HICON aIcon, ByteBuf* aOutBuffer) {
+ nsresult rv = NS_ERROR_FAILURE;
+
+ if (aIcon) {
+ // we got a handle to an icon. Now we want to get a bitmap for the icon
+ // using GetIconInfo....
+ ICONINFO iconInfo;
+ if (GetIconInfo(aIcon, &iconInfo)) {
+ // we got the bitmaps, first find out their size
+ HDC hDC = CreateCompatibleDC(nullptr); // get a device context for
+ // the screen.
+ BITMAPINFOHEADER maskHeader = {sizeof(BITMAPINFOHEADER)};
+ BITMAPINFOHEADER colorHeader = {sizeof(BITMAPINFOHEADER)};
+ int colorTableSize, maskTableSize;
+ if (GetDIBits(hDC, iconInfo.hbmMask, 0, 0, nullptr,
+ (BITMAPINFO*)&maskHeader, DIB_RGB_COLORS) &&
+ GetDIBits(hDC, iconInfo.hbmColor, 0, 0, nullptr,
+ (BITMAPINFO*)&colorHeader, DIB_RGB_COLORS) &&
+ maskHeader.biHeight == colorHeader.biHeight &&
+ maskHeader.biWidth == colorHeader.biWidth &&
+ colorHeader.biBitCount > 8 && colorHeader.biSizeImage > 0 &&
+ colorHeader.biWidth >= 0 && colorHeader.biWidth <= 255 &&
+ colorHeader.biHeight >= 0 && colorHeader.biHeight <= 255 &&
+ maskHeader.biSizeImage > 0 &&
+ (colorTableSize = GetColorTableSize(&colorHeader)) >= 0 &&
+ (maskTableSize = GetColorTableSize(&maskHeader)) >= 0) {
+ uint32_t iconSize = sizeof(ICONFILEHEADER) + sizeof(ICONENTRY) +
+ sizeof(BITMAPINFOHEADER) + colorHeader.biSizeImage +
+ maskHeader.biSizeImage;
+
+ if (!aOutBuffer->Allocate(iconSize)) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ } else {
+ uint8_t* whereTo = aOutBuffer->mData;
+ int howMuch;
+
+ // the data starts with an icon file header
+ ICONFILEHEADER iconHeader;
+ iconHeader.ifhReserved = 0;
+ iconHeader.ifhType = 1;
+ iconHeader.ifhCount = 1;
+ howMuch = sizeof(ICONFILEHEADER);
+ memcpy(whereTo, &iconHeader, howMuch);
+ whereTo += howMuch;
+
+ // followed by the single icon entry
+ ICONENTRY iconEntry;
+ iconEntry.ieWidth = static_cast<int8_t>(colorHeader.biWidth);
+ iconEntry.ieHeight = static_cast<int8_t>(colorHeader.biHeight);
+ iconEntry.ieColors = 0;
+ iconEntry.ieReserved = 0;
+ iconEntry.iePlanes = 1;
+ iconEntry.ieBitCount = colorHeader.biBitCount;
+ iconEntry.ieSizeImage = sizeof(BITMAPINFOHEADER) +
+ colorHeader.biSizeImage +
+ maskHeader.biSizeImage;
+ iconEntry.ieFileOffset = sizeof(ICONFILEHEADER) + sizeof(ICONENTRY);
+ howMuch = sizeof(ICONENTRY);
+ memcpy(whereTo, &iconEntry, howMuch);
+ whereTo += howMuch;
+
+ // followed by the bitmap info header
+ // (doubling the height because icons have two bitmaps)
+ colorHeader.biHeight *= 2;
+ colorHeader.biSizeImage += maskHeader.biSizeImage;
+ howMuch = sizeof(BITMAPINFOHEADER);
+ memcpy(whereTo, &colorHeader, howMuch);
+ whereTo += howMuch;
+ colorHeader.biHeight /= 2;
+ colorHeader.biSizeImage -= maskHeader.biSizeImage;
+
+ // followed by the XOR bitmap data (colorHeader)
+ // (you'd expect the color table to come here, but it apparently
+ // doesn't)
+ BITMAPINFO* colorInfo =
+ CreateBitmapInfo(&colorHeader, colorTableSize);
+ if (colorInfo &&
+ GetDIBits(hDC, iconInfo.hbmColor, 0, colorHeader.biHeight,
+ whereTo, colorInfo, DIB_RGB_COLORS)) {
+ whereTo += colorHeader.biSizeImage;
+
+ // and finally the AND bitmap data (maskHeader)
+ BITMAPINFO* maskInfo = CreateBitmapInfo(&maskHeader, maskTableSize);
+ if (maskInfo &&
+ GetDIBits(hDC, iconInfo.hbmMask, 0, maskHeader.biHeight,
+ whereTo, maskInfo, DIB_RGB_COLORS)) {
+ rv = NS_OK;
+ } // if we got bitmap bits
+ delete maskInfo;
+ } // if we got mask bits
+ delete colorInfo;
+ } // if we allocated the buffer
+ } // if we got mask size
+
+ DeleteDC(hDC);
+ DeleteObject(iconInfo.hbmColor);
+ DeleteObject(iconInfo.hbmMask);
+ } // if we got icon info
+ DestroyIcon(aIcon);
+ } // if we got an hIcon
+
+ return rv;
+}
+
+static nsresult GetIconHandleFromURLBlocking(nsIMozIconURI* aUrl,
+ HICON* aIcon) {
+ nsAutoCString stockIcon;
+ aUrl->GetStockIcon(stockIcon);
+ if (!stockIcon.IsEmpty()) {
+ return GetStockHIcon(aUrl, aIcon);
+ }
+
+ IconPathInfo iconPathInfo;
+ nsresult rv = ExtractIconPathInfoFromUrl(aUrl, &iconPathInfo);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction(
+ "GetIconHandleFromURLBlocking",
+ [&] { rv = GetIconHandleFromPathInfo(iconPathInfo, aIcon); });
+
+ RefPtr<nsIEventTarget> target = DecodePool::Singleton()->GetIOEventTarget();
+
+ nsresult dispatchResult = SyncRunnable::DispatchToThread(target, task);
+ NS_ENSURE_SUCCESS(dispatchResult, dispatchResult);
+
+ return rv;
+}
+
+static RefPtr<HIconPromise> GetIconHandleFromURLAsync(nsIMozIconURI* aUrl) {
+ RefPtr<HIconPromise::Private> promise = new HIconPromise::Private(__func__);
+
+ nsAutoCString stockIcon;
+ aUrl->GetStockIcon(stockIcon);
+ if (!stockIcon.IsEmpty()) {
+ HICON hIcon = nullptr;
+ nsresult rv = GetStockHIcon(aUrl, &hIcon);
+ if (NS_SUCCEEDED(rv)) {
+ promise->Resolve(hIcon, __func__);
+ } else {
+ promise->Reject(rv, __func__);
+ }
+ return promise;
+ }
+
+ IconPathInfo iconPathInfo;
+ nsresult rv = ExtractIconPathInfoFromUrl(aUrl, &iconPathInfo);
+ if (NS_FAILED(rv)) {
+ promise->Reject(rv, __func__);
+ return promise;
+ }
+
+ nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction(
+ "GetIconHandleFromURLAsync", [iconPathInfo, promise] {
+ HICON hIcon = nullptr;
+ nsresult rv = GetIconHandleFromPathInfo(iconPathInfo, &hIcon);
+ if (NS_SUCCEEDED(rv)) {
+ promise->Resolve(hIcon, __func__);
+ } else {
+ promise->Reject(rv, __func__);
+ }
+ });
+
+ RefPtr<nsIEventTarget> target = DecodePool::Singleton()->GetIOEventTarget();
+
+ rv = target->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
+ if (NS_FAILED(rv)) {
+ promise->Reject(rv, __func__);
+ }
+
+ return promise;
+}
+
+static RefPtr<nsIconChannel::ByteBufPromise> GetIconBufferFromURLAsync(
+ nsIMozIconURI* aUrl) {
+ RefPtr<nsIconChannel::ByteBufPromise::Private> promise =
+ new nsIconChannel::ByteBufPromise::Private(__func__);
+
+ GetIconHandleFromURLAsync(aUrl)->Then(
+ GetCurrentSerialEventTarget(), __func__,
+ [promise](HICON aIcon) {
+ ByteBuf iconBuffer;
+ nsresult rv = MakeIconBuffer(aIcon, &iconBuffer);
+ if (NS_SUCCEEDED(rv)) {
+ promise->Resolve(std::move(iconBuffer), __func__);
+ } else {
+ promise->Reject(rv, __func__);
+ }
+ },
+ [promise](nsresult rv) { promise->Reject(rv, __func__); });
+
+ return promise;
+}
+
+static nsresult WriteByteBufToOutputStream(const ByteBuf& aBuffer,
+ nsIAsyncOutputStream* aStream) {
+ uint32_t written = 0;
+ nsresult rv = aStream->Write(reinterpret_cast<const char*>(aBuffer.mData),
+ aBuffer.mLen, &written);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return (written == aBuffer.mLen) ? NS_OK : NS_ERROR_UNEXPECTED;
+}
+
+NS_IMPL_ISUPPORTS(nsIconChannel, nsIChannel, nsIRequest, nsIRequestObserver,
+ nsIStreamListener)
+
+// nsIconChannel methods
+nsIconChannel::nsIconChannel() {}
+
+nsIconChannel::~nsIconChannel() {
+ if (mLoadInfo) {
+ NS_ReleaseOnMainThread("nsIconChannel::mLoadInfo", mLoadInfo.forget());
+ }
+ if (mLoadGroup) {
+ NS_ReleaseOnMainThread("nsIconChannel::mLoadGroup", mLoadGroup.forget());
+ }
+}
+
+nsresult nsIconChannel::Init(nsIURI* uri) {
+ NS_ASSERTION(uri, "no uri");
+ mUrl = uri;
+ mOriginalURI = uri;
+ nsresult rv;
+ mPump = do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv);
+ return rv;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIRequest methods:
+
+NS_IMETHODIMP
+nsIconChannel::GetName(nsACString& result) { return mUrl->GetSpec(result); }
+
+NS_IMETHODIMP
+nsIconChannel::IsPending(bool* result) { return mPump->IsPending(result); }
+
+NS_IMETHODIMP
+nsIconChannel::GetStatus(nsresult* status) { return mPump->GetStatus(status); }
+
+NS_IMETHODIMP nsIconChannel::SetCanceledReason(const nsACString& aReason) {
+ return SetCanceledReasonImpl(aReason);
+}
+
+NS_IMETHODIMP nsIconChannel::GetCanceledReason(nsACString& aReason) {
+ return GetCanceledReasonImpl(aReason);
+}
+
+NS_IMETHODIMP nsIconChannel::CancelWithReason(nsresult aStatus,
+ const nsACString& aReason) {
+ return CancelWithReasonImpl(aStatus, aReason);
+}
+
+NS_IMETHODIMP
+nsIconChannel::Cancel(nsresult status) {
+ mCanceled = true;
+ return mPump->Cancel(status);
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetCanceled(bool* result) {
+ *result = mCanceled;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::Suspend(void) { return mPump->Suspend(); }
+
+NS_IMETHODIMP
+nsIconChannel::Resume(void) { return mPump->Resume(); }
+NS_IMETHODIMP
+nsIconChannel::GetLoadGroup(nsILoadGroup** aLoadGroup) {
+ *aLoadGroup = mLoadGroup;
+ NS_IF_ADDREF(*aLoadGroup);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) {
+ mLoadGroup = aLoadGroup;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetLoadFlags(uint32_t* aLoadAttributes) {
+ return mPump->GetLoadFlags(aLoadAttributes);
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetLoadFlags(uint32_t aLoadAttributes) {
+ return mPump->SetLoadFlags(aLoadAttributes);
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
+ return GetTRRModeImpl(aTRRMode);
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
+ return SetTRRModeImpl(aTRRMode);
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetIsDocument(bool* aIsDocument) {
+ return NS_GetIsDocumentChannel(this, aIsDocument);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIChannel methods:
+
+NS_IMETHODIMP
+nsIconChannel::GetOriginalURI(nsIURI** aURI) {
+ *aURI = mOriginalURI;
+ NS_ADDREF(*aURI);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetOriginalURI(nsIURI* aURI) {
+ NS_ENSURE_ARG_POINTER(aURI);
+ mOriginalURI = aURI;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetURI(nsIURI** aURI) {
+ *aURI = mUrl;
+ NS_IF_ADDREF(*aURI);
+ return NS_OK;
+}
+
+// static
+RefPtr<nsIconChannel::ByteBufPromise> nsIconChannel::GetIconAsync(
+ nsIURI* aURI) {
+ MOZ_ASSERT(XRE_IsParentProcess());
+
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIMozIconURI> iconURI(do_QueryInterface(aURI, &rv));
+ if (NS_FAILED(rv)) {
+ return ByteBufPromise::CreateAndReject(rv, __func__);
+ }
+
+ return GetIconBufferFromURLAsync(iconURI);
+}
+
+NS_IMETHODIMP
+nsIconChannel::Open(nsIInputStream** aStream) {
+ nsCOMPtr<nsIStreamListener> listener;
+ nsresult rv =
+ nsContentSecurityManager::doContentSecurityCheck(this, listener);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ MOZ_ASSERT(
+ mLoadInfo->GetSecurityMode() == 0 ||
+ mLoadInfo->GetInitialSecurityCheckDone() ||
+ (mLoadInfo->GetSecurityMode() ==
+ nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL &&
+ mLoadInfo->GetLoadingPrincipal() &&
+ mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal()),
+ "security flags in loadInfo but doContentSecurityCheck() not called");
+
+ // Double-check that we are actually an icon URL
+ nsCOMPtr<nsIMozIconURI> iconURI(do_QueryInterface(mUrl, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Get the handle for the given icon URI. This may involve the decode I/O
+ // thread, as we can only call SHGetFileInfo() from that thread
+ //
+ // Since this API is synchronous, this call will not return until the decode
+ // I/O thread returns with the icon handle
+ //
+ // Once we have the handle, we create a Windows ICO buffer with it and
+ // dump the buffer into the output end of the pipe. The input end will
+ // be returned to the caller
+ HICON hIcon = nullptr;
+ rv = GetIconHandleFromURLBlocking(iconURI, &hIcon);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ ByteBuf iconBuffer;
+ rv = MakeIconBuffer(hIcon, &iconBuffer);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Create the asynchronous pipe with a blocking read end
+ nsCOMPtr<nsIAsyncInputStream> inputStream;
+ nsCOMPtr<nsIAsyncOutputStream> outputStream;
+ NS_NewPipe2(getter_AddRefs(inputStream), getter_AddRefs(outputStream),
+ false /*nonBlockingInput*/, false /*nonBlockingOutput*/,
+ iconBuffer.mLen /*segmentSize*/, 1 /*segmentCount*/);
+
+ rv = WriteByteBufToOutputStream(iconBuffer, outputStream);
+
+ if (NS_SUCCEEDED(rv)) {
+ inputStream.forget(aStream);
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsIconChannel::AsyncOpen(nsIStreamListener* aListener) {
+ nsCOMPtr<nsIStreamListener> listener = aListener;
+ nsresult rv =
+ nsContentSecurityManager::doContentSecurityCheck(this, listener);
+ if (NS_FAILED(rv)) {
+ mCallbacks = nullptr;
+ return rv;
+ }
+
+ MOZ_ASSERT(
+ mLoadInfo->GetSecurityMode() == 0 ||
+ mLoadInfo->GetInitialSecurityCheckDone() ||
+ (mLoadInfo->GetSecurityMode() ==
+ nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL &&
+ mLoadInfo->GetLoadingPrincipal() &&
+ mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal()),
+ "security flags in loadInfo but doContentSecurityCheck() not called");
+
+ mListener = listener;
+
+ rv = StartAsyncOpen();
+ if (NS_FAILED(rv)) {
+ mListener = nullptr;
+ mCallbacks = nullptr;
+ return rv;
+ }
+
+ // Add ourself to the load group, if available
+ if (mLoadGroup) {
+ mLoadGroup->AddRequest(this, nullptr);
+ }
+
+ return NS_OK;
+}
+
+nsresult nsIconChannel::StartAsyncOpen() {
+ // Double-check that we are actually an icon URL
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIMozIconURI> iconURI(do_QueryInterface(mUrl, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Create the asynchronous pipe with a non-blocking read end
+ nsCOMPtr<nsIAsyncInputStream> inputStream;
+ nsCOMPtr<nsIAsyncOutputStream> outputStream;
+ NS_NewPipe2(getter_AddRefs(inputStream), getter_AddRefs(outputStream),
+ true /*nonBlockingInput*/, false /*nonBlockingOutput*/,
+ 0 /*segmentSize*/, UINT32_MAX /*segmentCount*/);
+
+ // If we are in content, we asynchronously request the ICO buffer from
+ // the parent process because the APIs to load icons don't work with
+ // Win32k Lockdown
+ using ContentChild = mozilla::dom::ContentChild;
+ if (auto* contentChild = ContentChild::GetSingleton()) {
+ RefPtr<ContentChild::GetSystemIconPromise> iconPromise =
+ contentChild->SendGetSystemIcon(mUrl);
+ if (!iconPromise) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ iconPromise->Then(
+ mozilla::GetCurrentSerialEventTarget(), __func__,
+ [outputStream](std::tuple<nsresult, mozilla::Maybe<ByteBuf>>&& aArg) {
+ nsresult rv = std::get<0>(aArg);
+ mozilla::Maybe<ByteBuf> iconBuffer = std::move(std::get<1>(aArg));
+
+ if (NS_SUCCEEDED(rv)) {
+ MOZ_RELEASE_ASSERT(iconBuffer);
+ rv = WriteByteBufToOutputStream(*iconBuffer, outputStream);
+ }
+
+ outputStream->CloseWithStatus(rv);
+ },
+ [outputStream](mozilla::ipc::ResponseRejectReason) {
+ outputStream->CloseWithStatus(NS_ERROR_FAILURE);
+ });
+ } else {
+ // Get the handle for the given icon URI. This may involve the decode I/O
+ // thread, as we can only call SHGetFileInfo() from that thread
+ //
+ // Once we have the handle, we create a Windows ICO buffer with it and
+ // dump the buffer into the output end of the pipe. The input end will be
+ // pumped to our attached nsIStreamListener
+ GetIconBufferFromURLAsync(iconURI)->Then(
+ GetCurrentSerialEventTarget(), __func__,
+ [outputStream](ByteBuf aIconBuffer) {
+ nsresult rv =
+ WriteByteBufToOutputStream(std::move(aIconBuffer), outputStream);
+ outputStream->CloseWithStatus(rv);
+ },
+ [outputStream](nsresult rv) { outputStream->CloseWithStatus(rv); });
+ }
+
+ // Use the main thread for the pumped events unless the load info
+ // specifies otherwise
+ nsCOMPtr<nsISerialEventTarget> listenerTarget =
+ nsContentUtils::GetEventTargetByLoadInfo(mLoadInfo,
+ mozilla::TaskCategory::Other);
+ if (!listenerTarget) {
+ listenerTarget = do_GetMainThread();
+ }
+
+ rv = mPump->Init(inputStream.get(), 0 /*segmentSize*/, 0 /*segmentCount*/,
+ false /*closeWhenDone*/, listenerTarget);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return mPump->AsyncRead(this);
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetContentType(nsACString& aContentType) {
+ aContentType.AssignLiteral(IMAGE_ICO);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetContentType(const nsACString& aContentType) {
+ // It doesn't make sense to set the content-type on this type
+ // of channel...
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP nsIconChannel::GetContentCharset(nsACString& aContentCharset) {
+ aContentCharset.Truncate();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetContentCharset(const nsACString& aContentCharset) {
+ // It doesn't make sense to set the content-charset on this type
+ // of channel...
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetContentDisposition(uint32_t* aContentDisposition) {
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetContentDisposition(uint32_t aContentDisposition) {
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetContentDispositionFilename(
+ nsAString& aContentDispositionFilename) {
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetContentDispositionFilename(
+ const nsAString& aContentDispositionFilename) {
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetContentDispositionHeader(
+ nsACString& aContentDispositionHeader) {
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetContentLength(int64_t* aContentLength) {
+ *aContentLength = 0;
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetContentLength(int64_t aContentLength) {
+ MOZ_ASSERT_UNREACHABLE("nsIconChannel::SetContentLength");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetOwner(nsISupports** aOwner) {
+ *aOwner = mOwner.get();
+ NS_IF_ADDREF(*aOwner);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetOwner(nsISupports* aOwner) {
+ mOwner = aOwner;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetLoadInfo(nsILoadInfo** aLoadInfo) {
+ NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) {
+ MOZ_RELEASE_ASSERT(aLoadInfo, "loadinfo can't be null");
+ mLoadInfo = aLoadInfo;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetNotificationCallbacks(
+ nsIInterfaceRequestor** aNotificationCallbacks) {
+ *aNotificationCallbacks = mCallbacks.get();
+ NS_IF_ADDREF(*aNotificationCallbacks);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::SetNotificationCallbacks(
+ nsIInterfaceRequestor* aNotificationCallbacks) {
+ mCallbacks = aNotificationCallbacks;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::GetSecurityInfo(nsITransportSecurityInfo** aSecurityInfo) {
+ *aSecurityInfo = nullptr;
+ return NS_OK;
+}
+
+// nsIRequestObserver methods
+NS_IMETHODIMP nsIconChannel::OnStartRequest(nsIRequest* aRequest) {
+ if (mListener) {
+ return mListener->OnStartRequest(this);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsIconChannel::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
+ if (mListener) {
+ mListener->OnStopRequest(this, aStatus);
+ mListener = nullptr;
+ }
+
+ // Remove from load group
+ if (mLoadGroup) {
+ mLoadGroup->RemoveRequest(this, nullptr, aStatus);
+ }
+
+ // Drop notification callbacks to prevent cycles.
+ mCallbacks = nullptr;
+
+ return NS_OK;
+}
+
+// nsIStreamListener methods
+NS_IMETHODIMP
+nsIconChannel::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aStream,
+ uint64_t aOffset, uint32_t aCount) {
+ if (mListener) {
+ return mListener->OnDataAvailable(this, aStream, aOffset, aCount);
+ }
+ return NS_OK;
+}
diff --git a/image/decoders/icon/win/nsIconChannel.h b/image/decoders/icon/win/nsIconChannel.h
new file mode 100644
index 0000000000..4065be76e3
--- /dev/null
+++ b/image/decoders/icon/win/nsIconChannel.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_encoders_icon_win_nsIconChannel_h
+#define mozilla_image_encoders_icon_win_nsIconChannel_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/MozPromise.h"
+
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "nsIChannel.h"
+#include "nsILoadGroup.h"
+#include "nsILoadInfo.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIURI.h"
+#include "nsIInputStreamPump.h"
+#include "nsIStreamListener.h"
+
+namespace mozilla::ipc {
+class ByteBuf;
+}
+
+class nsIconChannel final : public nsIChannel, public nsIStreamListener {
+ public:
+ using ByteBufPromise =
+ mozilla::MozPromise<mozilla::ipc::ByteBuf, nsresult, true>;
+
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIREQUEST
+ NS_DECL_NSICHANNEL
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSISTREAMLISTENER
+
+ nsIconChannel();
+
+ nsresult Init(nsIURI* uri);
+
+ /// Obtains an icon in Windows ICO format as a ByteBuf instead
+ /// of a channel. For use with IPC.
+ static RefPtr<ByteBufPromise> GetIconAsync(nsIURI* aURI);
+
+ private:
+ ~nsIconChannel();
+
+ nsresult StartAsyncOpen();
+
+ nsCOMPtr<nsIURI> mUrl;
+ nsCOMPtr<nsIURI> mOriginalURI;
+ nsCOMPtr<nsILoadGroup> mLoadGroup;
+ nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
+ nsCOMPtr<nsISupports> mOwner;
+ nsCOMPtr<nsILoadInfo> mLoadInfo;
+
+ nsCOMPtr<nsIInputStreamPump> mPump;
+ nsCOMPtr<nsIStreamListener> mListener;
+
+ bool mCanceled = false;
+};
+
+#endif // mozilla_image_encoders_icon_win_nsIconChannel_h
diff --git a/image/decoders/moz.build b/image/decoders/moz.build
new file mode 100644
index 0000000000..d7e062f843
--- /dev/null
+++ b/image/decoders/moz.build
@@ -0,0 +1,62 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+toolkit = CONFIG["MOZ_WIDGET_TOOLKIT"]
+
+# The Icon Channel stuff really shouldn't live in decoders/icon, but we'll
+# fix that another time.
+if toolkit == "gtk":
+ DIRS += ["icon/gtk", "icon"]
+
+if CONFIG["OS_ARCH"] == "WINNT":
+ DIRS += ["icon/win", "icon"]
+
+if toolkit == "cocoa":
+ DIRS += ["icon/mac", "icon"]
+elif toolkit == "android":
+ DIRS += ["icon/android", "icon"]
+
+UNIFIED_SOURCES += [
+ "EXIF.cpp",
+ "iccjpeg.c",
+ "nsBMPDecoder.cpp",
+ "nsGIFDecoder2.cpp",
+ "nsICODecoder.cpp",
+ "nsIconDecoder.cpp",
+ "nsJPEGDecoder.cpp",
+ "nsPNGDecoder.cpp",
+ "nsWebPDecoder.cpp",
+]
+
+if CONFIG["MOZ_AV1"]:
+ UNIFIED_SOURCES += [
+ "nsAVIFDecoder.cpp",
+ ]
+
+if CONFIG["MOZ_JXL"]:
+ UNIFIED_SOURCES += [
+ "nsJXLDecoder.cpp",
+ ]
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+LOCAL_INCLUDES += [
+ # Access to Skia headers for Downscaler.
+ "/gfx/2d",
+ # Decoders need ImageLib headers.
+ "/image",
+ # for libyuv::ARGBAttenuate and ::ARGBUnattenuate
+ "/media/libyuv/libyuv/include",
+]
+
+LOCAL_INCLUDES += CONFIG["SKIA_INCLUDES"]
+
+FINAL_LIBRARY = "xul"
+
+CXXFLAGS += ["-Werror=switch"]
+
+# Add libFuzzer configuration directives
+include("/tools/fuzzing/libfuzzer-config.mozbuild")
diff --git a/image/decoders/nsAVIFDecoder.cpp b/image/decoders/nsAVIFDecoder.cpp
new file mode 100644
index 0000000000..06b5a60086
--- /dev/null
+++ b/image/decoders/nsAVIFDecoder.cpp
@@ -0,0 +1,1991 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageLogging.h" // Must appear first
+
+#include "nsAVIFDecoder.h"
+
+#include "aom/aomdx.h"
+
+#include "DAV1DDecoder.h"
+#include "gfxPlatform.h"
+#include "YCbCrUtils.h"
+#include "libyuv.h"
+
+#include "SurfacePipeFactory.h"
+
+#include "mozilla/Telemetry.h"
+#include "mozilla/TelemetryComms.h"
+#include "mozilla/UniquePtrExtensions.h"
+
+using namespace mozilla::gfx;
+
+namespace mozilla {
+
+namespace image {
+
+using Telemetry::LABELS_AVIF_A1LX;
+using Telemetry::LABELS_AVIF_A1OP;
+using Telemetry::LABELS_AVIF_ALPHA;
+using Telemetry::LABELS_AVIF_AOM_DECODE_ERROR;
+using Telemetry::LABELS_AVIF_BIT_DEPTH;
+using Telemetry::LABELS_AVIF_CICP_CP;
+using Telemetry::LABELS_AVIF_CICP_MC;
+using Telemetry::LABELS_AVIF_CICP_TC;
+using Telemetry::LABELS_AVIF_CLAP;
+using Telemetry::LABELS_AVIF_COLR;
+using Telemetry::LABELS_AVIF_DECODE_RESULT;
+using Telemetry::LABELS_AVIF_DECODER;
+using Telemetry::LABELS_AVIF_GRID;
+using Telemetry::LABELS_AVIF_IPRO;
+using Telemetry::LABELS_AVIF_ISPE;
+using Telemetry::LABELS_AVIF_LSEL;
+using Telemetry::LABELS_AVIF_MAJOR_BRAND;
+using Telemetry::LABELS_AVIF_PASP;
+using Telemetry::LABELS_AVIF_PIXI;
+using Telemetry::LABELS_AVIF_SEQUENCE;
+using Telemetry::LABELS_AVIF_YUV_COLOR_SPACE;
+
+static LazyLogModule sAVIFLog("AVIFDecoder");
+
+static const LABELS_AVIF_BIT_DEPTH gColorDepthLabel[] = {
+ LABELS_AVIF_BIT_DEPTH::color_8, LABELS_AVIF_BIT_DEPTH::color_10,
+ LABELS_AVIF_BIT_DEPTH::color_12, LABELS_AVIF_BIT_DEPTH::color_16};
+
+static const LABELS_AVIF_YUV_COLOR_SPACE gColorSpaceLabel[] = {
+ LABELS_AVIF_YUV_COLOR_SPACE::BT601, LABELS_AVIF_YUV_COLOR_SPACE::BT709,
+ LABELS_AVIF_YUV_COLOR_SPACE::BT2020, LABELS_AVIF_YUV_COLOR_SPACE::identity};
+
+static MaybeIntSize GetImageSize(const Mp4parseAvifInfo& aInfo) {
+ // Note this does not take cropping via CleanAperture (clap) into account
+ const struct Mp4parseImageSpatialExtents* ispe = aInfo.spatial_extents;
+
+ if (ispe) {
+ // Decoder::PostSize takes int32_t, but ispe contains uint32_t
+ CheckedInt<int32_t> width = ispe->image_width;
+ CheckedInt<int32_t> height = ispe->image_height;
+
+ if (width.isValid() && height.isValid()) {
+ return Some(IntSize{width.value(), height.value()});
+ }
+ }
+
+ return Nothing();
+}
+
+// Translate the MIAF/HEIF-based orientation transforms (imir, irot) into
+// ImageLib's representation. Note that the interpretation of imir was reversed
+// Between HEIF (ISO 23008-12:2017) and ISO/IEC 23008-12:2017/DAmd 2. This is
+// handled by mp4parse. See mp4parse::read_imir for details.
+Orientation GetImageOrientation(const Mp4parseAvifInfo& aInfo) {
+ // Per MIAF (ISO/IEC 23000-22:2019) § 7.3.6.7
+ // These properties, if used, shall be indicated to be applied in the
+ // following order: clean aperture first, then rotation, then mirror.
+ // The Orientation type does the same order, but opposite rotation direction
+
+ const Mp4parseIrot heifRot = aInfo.image_rotation;
+ const Mp4parseImir* heifMir = aInfo.image_mirror;
+ Angle mozRot;
+ Flip mozFlip;
+
+ if (!heifMir) { // No mirroring
+ mozFlip = Flip::Unflipped;
+
+ switch (heifRot) {
+ case MP4PARSE_IROT_D0:
+ // ⥠ UPWARDS HARPOON WITH BARB LEFT FROM BAR
+ mozRot = Angle::D0;
+ break;
+ case MP4PARSE_IROT_D90:
+ // ⥞ LEFTWARDS HARPOON WITH BARB DOWN FROM BAR
+ mozRot = Angle::D270;
+ break;
+ case MP4PARSE_IROT_D180:
+ // ⥠DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR
+ mozRot = Angle::D180;
+ break;
+ case MP4PARSE_IROT_D270:
+ // ⥛ RIGHTWARDS HARPOON WITH BARB UP FROM BAR
+ mozRot = Angle::D90;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE();
+ }
+ } else {
+ MOZ_ASSERT(heifMir);
+ mozFlip = Flip::Horizontal;
+
+ enum class HeifFlippedOrientation : uint8_t {
+ IROT_D0_IMIR_V = (MP4PARSE_IROT_D0 << 1) | MP4PARSE_IMIR_LEFT_RIGHT,
+ IROT_D0_IMIR_H = (MP4PARSE_IROT_D0 << 1) | MP4PARSE_IMIR_TOP_BOTTOM,
+ IROT_D90_IMIR_V = (MP4PARSE_IROT_D90 << 1) | MP4PARSE_IMIR_LEFT_RIGHT,
+ IROT_D90_IMIR_H = (MP4PARSE_IROT_D90 << 1) | MP4PARSE_IMIR_TOP_BOTTOM,
+ IROT_D180_IMIR_V = (MP4PARSE_IROT_D180 << 1) | MP4PARSE_IMIR_LEFT_RIGHT,
+ IROT_D180_IMIR_H = (MP4PARSE_IROT_D180 << 1) | MP4PARSE_IMIR_TOP_BOTTOM,
+ IROT_D270_IMIR_V = (MP4PARSE_IROT_D270 << 1) | MP4PARSE_IMIR_LEFT_RIGHT,
+ IROT_D270_IMIR_H = (MP4PARSE_IROT_D270 << 1) | MP4PARSE_IMIR_TOP_BOTTOM,
+ };
+
+ HeifFlippedOrientation heifO =
+ HeifFlippedOrientation((heifRot << 1) | *heifMir);
+
+ switch (heifO) {
+ case HeifFlippedOrientation::IROT_D0_IMIR_V:
+ case HeifFlippedOrientation::IROT_D180_IMIR_H:
+ // ⥜ UPWARDS HARPOON WITH BARB RIGHT FROM BAR
+ mozRot = Angle::D0;
+ break;
+ case HeifFlippedOrientation::IROT_D270_IMIR_V:
+ case HeifFlippedOrientation::IROT_D90_IMIR_H:
+ // ⥚ LEFTWARDS HARPOON WITH BARB UP FROM BAR
+ mozRot = Angle::D90;
+ break;
+ case HeifFlippedOrientation::IROT_D180_IMIR_V:
+ case HeifFlippedOrientation::IROT_D0_IMIR_H:
+ // ⥡ DOWNWARDS HARPOON WITH BARB LEFT FROM BAR
+ mozRot = Angle::D180;
+ break;
+ case HeifFlippedOrientation::IROT_D90_IMIR_V:
+ case HeifFlippedOrientation::IROT_D270_IMIR_H:
+ // ⥟ RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR
+ mozRot = Angle::D270;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE();
+ }
+ }
+
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("GetImageOrientation: (rot%d, imir(%s)) -> (Angle%d, "
+ "Flip%d)",
+ static_cast<int>(heifRot),
+ heifMir ? (*heifMir == MP4PARSE_IMIR_LEFT_RIGHT ? "left-right"
+ : "top-bottom")
+ : "none",
+ static_cast<int>(mozRot), static_cast<int>(mozFlip)));
+ return Orientation{mozRot, mozFlip};
+}
+bool AVIFDecoderStream::ReadAt(int64_t offset, void* data, size_t size,
+ size_t* bytes_read) {
+ size = std::min(size, size_t(mBuffer->length() - offset));
+
+ if (size <= 0) {
+ return false;
+ }
+
+ memcpy(data, mBuffer->begin() + offset, size);
+ *bytes_read = size;
+ return true;
+}
+
+bool AVIFDecoderStream::Length(int64_t* size) {
+ *size =
+ static_cast<int64_t>(std::min<uint64_t>(mBuffer->length(), INT64_MAX));
+ return true;
+}
+
+const uint8_t* AVIFDecoderStream::GetContiguousAccess(int64_t aOffset,
+ size_t aSize) {
+ if (aOffset + aSize >= mBuffer->length()) {
+ return nullptr;
+ }
+
+ return mBuffer->begin() + aOffset;
+}
+
+AVIFParser::~AVIFParser() {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug, ("Destroy AVIFParser=%p", this));
+}
+
+Mp4parseStatus AVIFParser::Create(const Mp4parseIo* aIo, ByteStream* aBuffer,
+ UniquePtr<AVIFParser>& aParserOut,
+ bool aAllowSequences,
+ bool aAnimateAVIFMajor) {
+ MOZ_ASSERT(aIo);
+ MOZ_ASSERT(!aParserOut);
+
+ UniquePtr<AVIFParser> p(new AVIFParser(aIo));
+ Mp4parseStatus status = p->Init(aBuffer, aAllowSequences, aAnimateAVIFMajor);
+
+ if (status == MP4PARSE_STATUS_OK) {
+ MOZ_ASSERT(p->mParser);
+ aParserOut = std::move(p);
+ }
+
+ return status;
+}
+
+nsAVIFDecoder::DecodeResult AVIFParser::GetImage(AVIFImage& aImage) {
+ MOZ_ASSERT(mParser);
+
+ // If the AVIF is animated, get next frame and yield if sequence is not done.
+ if (IsAnimated()) {
+ aImage.mColorImage = mColorSampleIter->GetNext();
+
+ if (!aImage.mColorImage) {
+ return AsVariant(nsAVIFDecoder::NonDecoderResult::NoSamples);
+ }
+
+ aImage.mFrameNum = mFrameNum++;
+ int64_t durationMs = aImage.mColorImage->mDuration.ToMilliseconds();
+ aImage.mDuration = FrameTimeout::FromRawMilliseconds(
+ static_cast<int32_t>(std::min<int64_t>(durationMs, INT32_MAX)));
+
+ if (mAlphaSampleIter) {
+ aImage.mAlphaImage = mAlphaSampleIter->GetNext();
+ if (!aImage.mAlphaImage) {
+ return AsVariant(nsAVIFDecoder::NonDecoderResult::NoSamples);
+ }
+ }
+
+ bool hasNext = mColorSampleIter->HasNext();
+ if (mAlphaSampleIter && (hasNext != mAlphaSampleIter->HasNext())) {
+ MOZ_LOG(
+ sAVIFLog, LogLevel::Warning,
+ ("[this=%p] The %s sequence ends before frame %d, aborting decode.",
+ this, hasNext ? "alpha" : "color", mFrameNum));
+ return AsVariant(nsAVIFDecoder::NonDecoderResult::NoSamples);
+ }
+ if (!hasNext) {
+ return AsVariant(nsAVIFDecoder::NonDecoderResult::Complete);
+ }
+ return AsVariant(nsAVIFDecoder::NonDecoderResult::OutputAvailable);
+ }
+
+ if (!mInfo.has_primary_item) {
+ return AsVariant(nsAVIFDecoder::NonDecoderResult::NoSamples);
+ }
+
+ // If the AVIF is not animated, get the pitm image and return Complete.
+ Mp4parseAvifImage image = {};
+ Mp4parseStatus status = mp4parse_avif_get_image(mParser.get(), &image);
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] mp4parse_avif_get_image -> %d; primary_item length: "
+ "%zu, alpha_item length: %zu",
+ this, status, image.primary_image.length, image.alpha_image.length));
+ if (status != MP4PARSE_STATUS_OK) {
+ return AsVariant(status);
+ }
+
+ MOZ_ASSERT(image.primary_image.data);
+ RefPtr<MediaRawData> colorImage =
+ new MediaRawData(image.primary_image.data, image.primary_image.length);
+ RefPtr<MediaRawData> alphaImage = nullptr;
+
+ if (image.alpha_image.length) {
+ alphaImage =
+ new MediaRawData(image.alpha_image.data, image.alpha_image.length);
+ }
+
+ aImage.mFrameNum = 0;
+ aImage.mDuration = FrameTimeout::Forever();
+ aImage.mColorImage = colorImage;
+ aImage.mAlphaImage = alphaImage;
+ return AsVariant(nsAVIFDecoder::NonDecoderResult::Complete);
+}
+
+AVIFParser::AVIFParser(const Mp4parseIo* aIo) : mIo(aIo) {
+ MOZ_ASSERT(mIo);
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("Create AVIFParser=%p, image.avif.compliance_strictness: %d", this,
+ StaticPrefs::image_avif_compliance_strictness()));
+}
+
+static Mp4parseStatus CreateSampleIterator(
+ Mp4parseAvifParser* aParser, ByteStream* aBuffer, uint32_t trackID,
+ UniquePtr<SampleIterator>& aIteratorOut) {
+ Mp4parseByteData data;
+ uint64_t timescale;
+ Mp4parseStatus rv =
+ mp4parse_avif_get_indice_table(aParser, trackID, &data, &timescale);
+ if (rv != MP4PARSE_STATUS_OK) {
+ return rv;
+ }
+
+ UniquePtr<IndiceWrapper> wrapper = MakeUnique<IndiceWrapper>(data);
+ RefPtr<MP4SampleIndex> index = new MP4SampleIndex(
+ *wrapper, aBuffer, trackID, false, AssertedCast<int32_t>(timescale));
+ aIteratorOut = MakeUnique<SampleIterator>(index);
+ return MP4PARSE_STATUS_OK;
+}
+
+Mp4parseStatus AVIFParser::Init(ByteStream* aBuffer, bool aAllowSequences,
+ bool aAnimateAVIFMajor) {
+#define CHECK_MP4PARSE_STATUS(v) \
+ do { \
+ if ((v) != MP4PARSE_STATUS_OK) { \
+ return v; \
+ } \
+ } while (false)
+
+ MOZ_ASSERT(!mParser);
+
+ Mp4parseAvifParser* parser = nullptr;
+ Mp4parseStatus status =
+ mp4parse_avif_new(mIo,
+ static_cast<enum Mp4parseStrictness>(
+ StaticPrefs::image_avif_compliance_strictness()),
+ &parser);
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] mp4parse_avif_new status: %d", this, status));
+ CHECK_MP4PARSE_STATUS(status);
+ MOZ_ASSERT(parser);
+ mParser.reset(parser);
+
+ status = mp4parse_avif_get_info(mParser.get(), &mInfo);
+ CHECK_MP4PARSE_STATUS(status);
+
+ bool useSequence = mInfo.has_sequence;
+ if (useSequence) {
+ if (!aAllowSequences) {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] AVIF sequences disabled", this));
+ useSequence = false;
+ } else if (!aAnimateAVIFMajor &&
+ !!memcmp(mInfo.major_brand, "avis", sizeof(mInfo.major_brand))) {
+ useSequence = false;
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] AVIF prefers still image", this));
+ }
+ }
+
+ if (useSequence) {
+ status = CreateSampleIterator(parser, aBuffer, mInfo.color_track_id,
+ mColorSampleIter);
+ CHECK_MP4PARSE_STATUS(status);
+ MOZ_ASSERT(mColorSampleIter);
+
+ if (mInfo.alpha_track_id) {
+ status = CreateSampleIterator(parser, aBuffer, mInfo.alpha_track_id,
+ mAlphaSampleIter);
+ CHECK_MP4PARSE_STATUS(status);
+ MOZ_ASSERT(mAlphaSampleIter);
+ }
+ }
+
+ return status;
+}
+
+bool AVIFParser::IsAnimated() const { return !!mColorSampleIter; }
+
+// The gfx::YUVColorSpace value is only used in the conversion from YUV -> RGB.
+// Typically this comes directly from the CICP matrix_coefficients value, but
+// certain values require additionally considering the colour_primaries value.
+// See `gfxUtils::CicpToColorSpace` for details. We return a gfx::YUVColorSpace
+// rather than CICP::MatrixCoefficients, since that's what
+// `gfx::ConvertYCbCrATo[A]RGB` uses. `aBitstreamColorSpaceFunc` abstracts the
+// fact that different decoder libraries require different methods for
+// extracting the CICP values from the AV1 bitstream and we don't want to do
+// that work unnecessarily because in addition to wasted effort, it would make
+// the logging more confusing.
+template <typename F>
+static gfx::YUVColorSpace GetAVIFColorSpace(
+ const Mp4parseNclxColourInformation* aNclx, F&& aBitstreamColorSpaceFunc) {
+ return ToMaybe(aNclx)
+ .map([=](const auto& nclx) {
+ return gfxUtils::CicpToColorSpace(
+ static_cast<CICP::MatrixCoefficients>(nclx.matrix_coefficients),
+ static_cast<CICP::ColourPrimaries>(nclx.colour_primaries),
+ sAVIFLog);
+ })
+ .valueOrFrom(aBitstreamColorSpaceFunc)
+ .valueOr(gfx::YUVColorSpace::BT601);
+}
+
+static gfx::ColorRange GetAVIFColorRange(
+ const Mp4parseNclxColourInformation* aNclx,
+ const gfx::ColorRange av1ColorRange) {
+ return ToMaybe(aNclx)
+ .map([=](const auto& nclx) {
+ return aNclx->full_range_flag ? gfx::ColorRange::FULL
+ : gfx::ColorRange::LIMITED;
+ })
+ .valueOr(av1ColorRange);
+}
+
+void AVIFDecodedData::SetCicpValues(
+ const Mp4parseNclxColourInformation* aNclx,
+ const gfx::CICP::ColourPrimaries aAv1ColourPrimaries,
+ const gfx::CICP::TransferCharacteristics aAv1TransferCharacteristics,
+ const gfx::CICP::MatrixCoefficients aAv1MatrixCoefficients) {
+ auto cp = CICP::ColourPrimaries::CP_UNSPECIFIED;
+ auto tc = CICP::TransferCharacteristics::TC_UNSPECIFIED;
+ auto mc = CICP::MatrixCoefficients::MC_UNSPECIFIED;
+
+ if (aNclx) {
+ cp = static_cast<CICP::ColourPrimaries>(aNclx->colour_primaries);
+ tc = static_cast<CICP::TransferCharacteristics>(
+ aNclx->transfer_characteristics);
+ mc = static_cast<CICP::MatrixCoefficients>(aNclx->matrix_coefficients);
+ }
+
+ if (cp == CICP::ColourPrimaries::CP_UNSPECIFIED) {
+ if (aAv1ColourPrimaries != CICP::ColourPrimaries::CP_UNSPECIFIED) {
+ cp = aAv1ColourPrimaries;
+ MOZ_LOG(sAVIFLog, LogLevel::Info,
+ ("Unspecified colour_primaries value specified in colr box, "
+ "using AV1 sequence header (%hhu)",
+ cp));
+ } else {
+ cp = CICP::ColourPrimaries::CP_BT709;
+ MOZ_LOG(sAVIFLog, LogLevel::Warning,
+ ("Unspecified colour_primaries value specified in colr box "
+ "or AV1 sequence header, using fallback value (%hhu)",
+ cp));
+ }
+ } else if (cp != aAv1ColourPrimaries) {
+ MOZ_LOG(sAVIFLog, LogLevel::Warning,
+ ("colour_primaries mismatch: colr box = %hhu, AV1 "
+ "sequence header = %hhu, using colr box",
+ cp, aAv1ColourPrimaries));
+ }
+
+ if (tc == CICP::TransferCharacteristics::TC_UNSPECIFIED) {
+ if (aAv1TransferCharacteristics !=
+ CICP::TransferCharacteristics::TC_UNSPECIFIED) {
+ tc = aAv1TransferCharacteristics;
+ MOZ_LOG(sAVIFLog, LogLevel::Info,
+ ("Unspecified transfer_characteristics value specified in "
+ "colr box, using AV1 sequence header (%hhu)",
+ tc));
+ } else {
+ tc = CICP::TransferCharacteristics::TC_SRGB;
+ MOZ_LOG(sAVIFLog, LogLevel::Warning,
+ ("Unspecified transfer_characteristics value specified in "
+ "colr box or AV1 sequence header, using fallback value (%hhu)",
+ tc));
+ }
+ } else if (tc != aAv1TransferCharacteristics) {
+ MOZ_LOG(sAVIFLog, LogLevel::Warning,
+ ("transfer_characteristics mismatch: colr box = %hhu, "
+ "AV1 sequence header = %hhu, using colr box",
+ tc, aAv1TransferCharacteristics));
+ }
+
+ if (mc == CICP::MatrixCoefficients::MC_UNSPECIFIED) {
+ if (aAv1MatrixCoefficients != CICP::MatrixCoefficients::MC_UNSPECIFIED) {
+ mc = aAv1MatrixCoefficients;
+ MOZ_LOG(sAVIFLog, LogLevel::Info,
+ ("Unspecified matrix_coefficients value specified in "
+ "colr box, using AV1 sequence header (%hhu)",
+ mc));
+ } else {
+ mc = CICP::MatrixCoefficients::MC_BT601;
+ MOZ_LOG(sAVIFLog, LogLevel::Warning,
+ ("Unspecified matrix_coefficients value specified in "
+ "colr box or AV1 sequence header, using fallback value (%hhu)",
+ mc));
+ }
+ } else if (mc != aAv1MatrixCoefficients) {
+ MOZ_LOG(sAVIFLog, LogLevel::Warning,
+ ("matrix_coefficients mismatch: colr box = %hhu, "
+ "AV1 sequence header = %hhu, using colr box",
+ mc, aAv1TransferCharacteristics));
+ }
+
+ mColourPrimaries = cp;
+ mTransferCharacteristics = tc;
+ mMatrixCoefficients = mc;
+}
+
+class Dav1dDecoder final : AVIFDecoderInterface {
+ public:
+ ~Dav1dDecoder() {
+ MOZ_LOG(sAVIFLog, LogLevel::Verbose, ("Destroy Dav1dDecoder=%p", this));
+
+ if (mColorContext) {
+ dav1d_close(&mColorContext);
+ MOZ_ASSERT(!mColorContext);
+ }
+
+ if (mAlphaContext) {
+ dav1d_close(&mAlphaContext);
+ MOZ_ASSERT(!mAlphaContext);
+ }
+ }
+
+ static DecodeResult Create(UniquePtr<AVIFDecoderInterface>& aDecoder,
+ bool aHasAlpha) {
+ UniquePtr<Dav1dDecoder> d(new Dav1dDecoder());
+ Dav1dResult r = d->Init(aHasAlpha);
+ if (r == 0) {
+ aDecoder.reset(d.release());
+ }
+ return AsVariant(r);
+ }
+
+ DecodeResult Decode(bool aShouldSendTelemetry,
+ const Mp4parseAvifInfo& aAVIFInfo,
+ const AVIFImage& aSamples) override {
+ MOZ_ASSERT(mColorContext);
+ MOZ_ASSERT(!mDecodedData);
+ MOZ_ASSERT(aSamples.mColorImage);
+
+ MOZ_LOG(sAVIFLog, LogLevel::Verbose, ("[this=%p] Decoding color", this));
+
+ OwnedDav1dPicture colorPic = OwnedDav1dPicture(new Dav1dPicture());
+ OwnedDav1dPicture alphaPic = nullptr;
+ Dav1dResult r = GetPicture(*mColorContext, *aSamples.mColorImage,
+ colorPic.get(), aShouldSendTelemetry);
+ if (r != 0) {
+ return AsVariant(r);
+ }
+
+ if (aSamples.mAlphaImage) {
+ MOZ_ASSERT(mAlphaContext);
+ MOZ_LOG(sAVIFLog, LogLevel::Verbose, ("[this=%p] Decoding alpha", this));
+
+ alphaPic = OwnedDav1dPicture(new Dav1dPicture());
+ r = GetPicture(*mAlphaContext, *aSamples.mAlphaImage, alphaPic.get(),
+ aShouldSendTelemetry);
+ if (r != 0) {
+ return AsVariant(r);
+ }
+
+ // Per § 4 of the AVIF spec
+ // https://aomediacodec.github.io/av1-avif/#auxiliary-images: An AV1
+ // Alpha Image Item […] shall be encoded with the same bit depth as the
+ // associated master AV1 Image Item
+ if (colorPic->p.bpc != alphaPic->p.bpc) {
+ return AsVariant(NonDecoderResult::AlphaYColorDepthMismatch);
+ }
+
+ if (colorPic->stride[0] != alphaPic->stride[0]) {
+ return AsVariant(NonDecoderResult::AlphaYSizeMismatch);
+ }
+ }
+
+ MOZ_ASSERT_IF(!alphaPic, !aAVIFInfo.premultiplied_alpha);
+ mDecodedData = Dav1dPictureToDecodedData(
+ aAVIFInfo.nclx_colour_information, std::move(colorPic),
+ std::move(alphaPic), aAVIFInfo.premultiplied_alpha);
+
+ return AsVariant(r);
+ }
+
+ private:
+ explicit Dav1dDecoder() {
+ MOZ_LOG(sAVIFLog, LogLevel::Verbose, ("Create Dav1dDecoder=%p", this));
+ }
+
+ Dav1dResult Init(bool aHasAlpha) {
+ MOZ_ASSERT(!mColorContext);
+ MOZ_ASSERT(!mAlphaContext);
+
+ Dav1dSettings settings;
+ dav1d_default_settings(&settings);
+ settings.all_layers = 0;
+ settings.max_frame_delay = 1;
+ // TODO: tune settings a la DAV1DDecoder for AV1 (Bug 1681816)
+
+ Dav1dResult r = dav1d_open(&mColorContext, &settings);
+ if (r != 0) {
+ return r;
+ }
+ MOZ_ASSERT(mColorContext);
+
+ if (aHasAlpha) {
+ r = dav1d_open(&mAlphaContext, &settings);
+ if (r != 0) {
+ return r;
+ }
+ MOZ_ASSERT(mAlphaContext);
+ }
+
+ return 0;
+ }
+
+ static Dav1dResult GetPicture(Dav1dContext& aContext,
+ const MediaRawData& aBytes,
+ Dav1dPicture* aPicture,
+ bool aShouldSendTelemetry) {
+ MOZ_ASSERT(aPicture);
+
+ Dav1dData dav1dData;
+ Dav1dResult r = dav1d_data_wrap(&dav1dData, aBytes.Data(), aBytes.Size(),
+ Dav1dFreeCallback_s, nullptr);
+
+ MOZ_LOG(
+ sAVIFLog, r == 0 ? LogLevel::Verbose : LogLevel::Error,
+ ("dav1d_data_wrap(%p, %zu) -> %d", dav1dData.data, dav1dData.sz, r));
+
+ if (r != 0) {
+ return r;
+ }
+
+ r = dav1d_send_data(&aContext, &dav1dData);
+
+ MOZ_LOG(sAVIFLog, r == 0 ? LogLevel::Debug : LogLevel::Error,
+ ("dav1d_send_data -> %d", r));
+
+ if (r != 0) {
+ return r;
+ }
+
+ r = dav1d_get_picture(&aContext, aPicture);
+
+ MOZ_LOG(sAVIFLog, r == 0 ? LogLevel::Debug : LogLevel::Error,
+ ("dav1d_get_picture -> %d", r));
+
+ // We already have the AVIF_DECODE_RESULT histogram to record all the
+ // successful calls, so only bother recording what type of errors we see
+ // via events. Unlike AOM, dav1d returns an int, not an enum, so this is
+ // the easiest way to see if we're getting unexpected behavior to
+ // investigate.
+ if (aShouldSendTelemetry && r != 0) {
+ // Uncomment once bug 1691156 is fixed
+ // mozilla::Telemetry::SetEventRecordingEnabled("avif"_ns, true);
+
+ mozilla::Telemetry::RecordEvent(
+ mozilla::Telemetry::EventID::Avif_Dav1dGetPicture_ReturnValue,
+ Some(nsPrintfCString("%d", r)), Nothing());
+ }
+
+ return r;
+ }
+
+ // A dummy callback for dav1d_data_wrap
+ static void Dav1dFreeCallback_s(const uint8_t* aBuf, void* aCookie) {
+ // The buf is managed by the mParser inside Dav1dDecoder itself. Do
+ // nothing here.
+ }
+
+ static UniquePtr<AVIFDecodedData> Dav1dPictureToDecodedData(
+ const Mp4parseNclxColourInformation* aNclx, OwnedDav1dPicture aPicture,
+ OwnedDav1dPicture aAlphaPlane, bool aPremultipliedAlpha);
+
+ Dav1dContext* mColorContext = nullptr;
+ Dav1dContext* mAlphaContext = nullptr;
+};
+
+OwnedAOMImage::OwnedAOMImage() {
+ MOZ_LOG(sAVIFLog, LogLevel::Verbose, ("Create OwnedAOMImage=%p", this));
+}
+
+OwnedAOMImage::~OwnedAOMImage() {
+ MOZ_LOG(sAVIFLog, LogLevel::Verbose, ("Destroy OwnedAOMImage=%p", this));
+}
+
+bool OwnedAOMImage::CloneFrom(aom_image_t* aImage, bool aIsAlpha) {
+ MOZ_ASSERT(aImage);
+ MOZ_ASSERT(!mImage);
+ MOZ_ASSERT(!mBuffer);
+
+ uint8_t* srcY = aImage->planes[AOM_PLANE_Y];
+ int yStride = aImage->stride[AOM_PLANE_Y];
+ int yHeight = aom_img_plane_height(aImage, AOM_PLANE_Y);
+ size_t yBufSize = yStride * yHeight;
+
+ // If aImage is alpha plane. The data is located in Y channel.
+ if (aIsAlpha) {
+ mBuffer = MakeUniqueFallible<uint8_t[]>(yBufSize);
+ if (!mBuffer) {
+ return false;
+ }
+ uint8_t* destY = mBuffer.get();
+ memcpy(destY, srcY, yBufSize);
+ mImage.emplace(*aImage);
+ mImage->planes[AOM_PLANE_Y] = destY;
+
+ return true;
+ }
+
+ uint8_t* srcCb = aImage->planes[AOM_PLANE_U];
+ int cbStride = aImage->stride[AOM_PLANE_U];
+ int cbHeight = aom_img_plane_height(aImage, AOM_PLANE_U);
+ size_t cbBufSize = cbStride * cbHeight;
+
+ uint8_t* srcCr = aImage->planes[AOM_PLANE_V];
+ int crStride = aImage->stride[AOM_PLANE_V];
+ int crHeight = aom_img_plane_height(aImage, AOM_PLANE_V);
+ size_t crBufSize = crStride * crHeight;
+
+ mBuffer = MakeUniqueFallible<uint8_t[]>(yBufSize + cbBufSize + crBufSize);
+ if (!mBuffer) {
+ return false;
+ }
+
+ uint8_t* destY = mBuffer.get();
+ uint8_t* destCb = destY + yBufSize;
+ uint8_t* destCr = destCb + cbBufSize;
+
+ memcpy(destY, srcY, yBufSize);
+ memcpy(destCb, srcCb, cbBufSize);
+ memcpy(destCr, srcCr, crBufSize);
+
+ mImage.emplace(*aImage);
+ mImage->planes[AOM_PLANE_Y] = destY;
+ mImage->planes[AOM_PLANE_U] = destCb;
+ mImage->planes[AOM_PLANE_V] = destCr;
+
+ return true;
+}
+
+/* static */
+OwnedAOMImage* OwnedAOMImage::CopyFrom(aom_image_t* aImage, bool aIsAlpha) {
+ MOZ_ASSERT(aImage);
+ UniquePtr<OwnedAOMImage> img(new OwnedAOMImage());
+ if (!img->CloneFrom(aImage, aIsAlpha)) {
+ return nullptr;
+ }
+ return img.release();
+}
+
+class AOMDecoder final : AVIFDecoderInterface {
+ public:
+ ~AOMDecoder() {
+ MOZ_LOG(sAVIFLog, LogLevel::Verbose, ("Destroy AOMDecoder=%p", this));
+
+ if (mColorContext.isSome()) {
+ aom_codec_err_t r = aom_codec_destroy(mColorContext.ptr());
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] aom_codec_destroy -> %d", this, r));
+ }
+
+ if (mAlphaContext.isSome()) {
+ aom_codec_err_t r = aom_codec_destroy(mAlphaContext.ptr());
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] aom_codec_destroy -> %d", this, r));
+ }
+ }
+
+ static DecodeResult Create(UniquePtr<AVIFDecoderInterface>& aDecoder,
+ bool aHasAlpha) {
+ UniquePtr<AOMDecoder> d(new AOMDecoder());
+ aom_codec_err_t e = d->Init(aHasAlpha);
+ if (e == AOM_CODEC_OK) {
+ aDecoder.reset(d.release());
+ }
+ return AsVariant(AOMResult(e));
+ }
+
+ DecodeResult Decode(bool aShouldSendTelemetry,
+ const Mp4parseAvifInfo& aAVIFInfo,
+ const AVIFImage& aSamples) override {
+ MOZ_ASSERT(mColorContext.isSome());
+ MOZ_ASSERT(!mDecodedData);
+ MOZ_ASSERT(aSamples.mColorImage);
+
+ aom_image_t* aomImg = nullptr;
+ DecodeResult r = GetImage(*mColorContext, *aSamples.mColorImage, &aomImg,
+ aShouldSendTelemetry);
+ if (!IsDecodeSuccess(r)) {
+ return r;
+ }
+ MOZ_ASSERT(aomImg);
+
+ // The aomImg will be released in next GetImage call (aom_codec_decode
+ // actually). The GetImage could be called again immediately if parsedImg
+ // contains alpha data. Therefore, we need to copy the image and manage it
+ // by AOMDecoder itself.
+ OwnedAOMImage* clonedImg = OwnedAOMImage::CopyFrom(aomImg, false);
+ if (!clonedImg) {
+ return AsVariant(NonDecoderResult::OutOfMemory);
+ }
+ mOwnedImage.reset(clonedImg);
+
+ if (aSamples.mAlphaImage) {
+ MOZ_ASSERT(mAlphaContext.isSome());
+
+ aom_image_t* alphaImg = nullptr;
+ r = GetImage(*mAlphaContext, *aSamples.mAlphaImage, &alphaImg,
+ aShouldSendTelemetry);
+ if (!IsDecodeSuccess(r)) {
+ return r;
+ }
+ MOZ_ASSERT(alphaImg);
+
+ OwnedAOMImage* clonedAlphaImg = OwnedAOMImage::CopyFrom(alphaImg, true);
+ if (!clonedAlphaImg) {
+ return AsVariant(NonDecoderResult::OutOfMemory);
+ }
+ mOwnedAlphaPlane.reset(clonedAlphaImg);
+
+ // Per § 4 of the AVIF spec
+ // https://aomediacodec.github.io/av1-avif/#auxiliary-images: An AV1
+ // Alpha Image Item […] shall be encoded with the same bit depth as the
+ // associated master AV1 Image Item
+ MOZ_ASSERT(mOwnedImage->GetImage() && mOwnedAlphaPlane->GetImage());
+ if (mOwnedImage->GetImage()->bit_depth !=
+ mOwnedAlphaPlane->GetImage()->bit_depth) {
+ return AsVariant(NonDecoderResult::AlphaYColorDepthMismatch);
+ }
+
+ if (mOwnedImage->GetImage()->stride[AOM_PLANE_Y] !=
+ mOwnedAlphaPlane->GetImage()->stride[AOM_PLANE_Y]) {
+ return AsVariant(NonDecoderResult::AlphaYSizeMismatch);
+ }
+ }
+
+ MOZ_ASSERT_IF(!mOwnedAlphaPlane, !aAVIFInfo.premultiplied_alpha);
+ mDecodedData = AOMImageToToDecodedData(
+ aAVIFInfo.nclx_colour_information, std::move(mOwnedImage),
+ std::move(mOwnedAlphaPlane), aAVIFInfo.premultiplied_alpha);
+
+ return r;
+ }
+
+ private:
+ explicit AOMDecoder() {
+ MOZ_LOG(sAVIFLog, LogLevel::Verbose, ("Create AOMDecoder=%p", this));
+ }
+
+ aom_codec_err_t Init(bool aHasAlpha) {
+ MOZ_ASSERT(mColorContext.isNothing());
+ MOZ_ASSERT(mAlphaContext.isNothing());
+
+ aom_codec_iface_t* iface = aom_codec_av1_dx();
+
+ // Init color decoder context
+ mColorContext.emplace();
+ aom_codec_err_t r = aom_codec_dec_init(
+ mColorContext.ptr(), iface, /* cfg = */ nullptr, /* flags = */ 0);
+
+ MOZ_LOG(sAVIFLog, r == AOM_CODEC_OK ? LogLevel::Verbose : LogLevel::Error,
+ ("[this=%p] color decoder: aom_codec_dec_init -> %d, name = %s",
+ this, r, mColorContext->name));
+
+ if (r != AOM_CODEC_OK) {
+ mColorContext.reset();
+ return r;
+ }
+
+ if (aHasAlpha) {
+ // Init alpha decoder context
+ mAlphaContext.emplace();
+ r = aom_codec_dec_init(mAlphaContext.ptr(), iface, /* cfg = */ nullptr,
+ /* flags = */ 0);
+
+ MOZ_LOG(sAVIFLog, r == AOM_CODEC_OK ? LogLevel::Verbose : LogLevel::Error,
+ ("[this=%p] color decoder: aom_codec_dec_init -> %d, name = %s",
+ this, r, mAlphaContext->name));
+
+ if (r != AOM_CODEC_OK) {
+ mAlphaContext.reset();
+ return r;
+ }
+ }
+
+ return r;
+ }
+
+ static DecodeResult GetImage(aom_codec_ctx_t& aContext,
+ const MediaRawData& aData, aom_image_t** aImage,
+ bool aShouldSendTelemetry) {
+ aom_codec_err_t r =
+ aom_codec_decode(&aContext, aData.Data(), aData.Size(), nullptr);
+
+ MOZ_LOG(sAVIFLog, r == AOM_CODEC_OK ? LogLevel::Verbose : LogLevel::Error,
+ ("aom_codec_decode -> %d", r));
+
+ if (aShouldSendTelemetry) {
+ switch (r) {
+ case AOM_CODEC_OK:
+ // No need to record any telemetry for the common case
+ break;
+ case AOM_CODEC_ERROR:
+ AccumulateCategorical(LABELS_AVIF_AOM_DECODE_ERROR::error);
+ break;
+ case AOM_CODEC_MEM_ERROR:
+ AccumulateCategorical(LABELS_AVIF_AOM_DECODE_ERROR::mem_error);
+ break;
+ case AOM_CODEC_ABI_MISMATCH:
+ AccumulateCategorical(LABELS_AVIF_AOM_DECODE_ERROR::abi_mismatch);
+ break;
+ case AOM_CODEC_INCAPABLE:
+ AccumulateCategorical(LABELS_AVIF_AOM_DECODE_ERROR::incapable);
+ break;
+ case AOM_CODEC_UNSUP_BITSTREAM:
+ AccumulateCategorical(LABELS_AVIF_AOM_DECODE_ERROR::unsup_bitstream);
+ break;
+ case AOM_CODEC_UNSUP_FEATURE:
+ AccumulateCategorical(LABELS_AVIF_AOM_DECODE_ERROR::unsup_feature);
+ break;
+ case AOM_CODEC_CORRUPT_FRAME:
+ AccumulateCategorical(LABELS_AVIF_AOM_DECODE_ERROR::corrupt_frame);
+ break;
+ case AOM_CODEC_INVALID_PARAM:
+ AccumulateCategorical(LABELS_AVIF_AOM_DECODE_ERROR::invalid_param);
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE(
+ "Unknown aom_codec_err_t value from aom_codec_decode");
+ }
+ }
+
+ if (r != AOM_CODEC_OK) {
+ return AsVariant(AOMResult(r));
+ }
+
+ aom_codec_iter_t iter = nullptr;
+ aom_image_t* img = aom_codec_get_frame(&aContext, &iter);
+
+ MOZ_LOG(sAVIFLog, img == nullptr ? LogLevel::Error : LogLevel::Verbose,
+ ("aom_codec_get_frame -> %p", img));
+
+ if (img == nullptr) {
+ return AsVariant(AOMResult(NonAOMCodecError::NoFrame));
+ }
+
+ const CheckedInt<int> decoded_width = img->d_w;
+ const CheckedInt<int> decoded_height = img->d_h;
+
+ if (!decoded_height.isValid() || !decoded_width.isValid()) {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("image dimensions can't be stored in int: d_w: %u, "
+ "d_h: %u",
+ img->d_w, img->d_h));
+ return AsVariant(AOMResult(NonAOMCodecError::SizeOverflow));
+ }
+
+ *aImage = img;
+ return AsVariant(AOMResult(r));
+ }
+
+ static UniquePtr<AVIFDecodedData> AOMImageToToDecodedData(
+ const Mp4parseNclxColourInformation* aNclx,
+ UniquePtr<OwnedAOMImage> aImage, UniquePtr<OwnedAOMImage> aAlphaPlane,
+ bool aPremultipliedAlpha);
+
+ Maybe<aom_codec_ctx_t> mColorContext;
+ Maybe<aom_codec_ctx_t> mAlphaContext;
+ UniquePtr<OwnedAOMImage> mOwnedImage;
+ UniquePtr<OwnedAOMImage> mOwnedAlphaPlane;
+};
+
+/* static */
+UniquePtr<AVIFDecodedData> Dav1dDecoder::Dav1dPictureToDecodedData(
+ const Mp4parseNclxColourInformation* aNclx, OwnedDav1dPicture aPicture,
+ OwnedDav1dPicture aAlphaPlane, bool aPremultipliedAlpha) {
+ MOZ_ASSERT(aPicture);
+
+ static_assert(std::is_same<int, decltype(aPicture->p.w)>::value);
+ static_assert(std::is_same<int, decltype(aPicture->p.h)>::value);
+
+ UniquePtr<AVIFDecodedData> data = MakeUnique<AVIFDecodedData>();
+
+ data->mRenderSize.emplace(aPicture->frame_hdr->render_width,
+ aPicture->frame_hdr->render_height);
+
+ data->mYChannel = static_cast<uint8_t*>(aPicture->data[0]);
+ data->mYStride = aPicture->stride[0];
+ data->mYSkip = aPicture->stride[0] - aPicture->p.w;
+ data->mCbChannel = static_cast<uint8_t*>(aPicture->data[1]);
+ data->mCrChannel = static_cast<uint8_t*>(aPicture->data[2]);
+ data->mCbCrStride = aPicture->stride[1];
+
+ switch (aPicture->p.layout) {
+ case DAV1D_PIXEL_LAYOUT_I400: // Monochrome, so no Cb or Cr channels
+ break;
+ case DAV1D_PIXEL_LAYOUT_I420:
+ data->mChromaSubsampling = ChromaSubsampling::HALF_WIDTH_AND_HEIGHT;
+ break;
+ case DAV1D_PIXEL_LAYOUT_I422:
+ data->mChromaSubsampling = ChromaSubsampling::HALF_WIDTH;
+ break;
+ case DAV1D_PIXEL_LAYOUT_I444:
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unknown pixel layout");
+ }
+
+ data->mCbSkip = aPicture->stride[1] - aPicture->p.w;
+ data->mCrSkip = aPicture->stride[1] - aPicture->p.w;
+ data->mPictureRect = IntRect(0, 0, aPicture->p.w, aPicture->p.h);
+ data->mStereoMode = StereoMode::MONO;
+ data->mColorDepth = ColorDepthForBitDepth(aPicture->p.bpc);
+
+ MOZ_ASSERT(aPicture->p.bpc == BitDepthForColorDepth(data->mColorDepth));
+
+ data->mYUVColorSpace = GetAVIFColorSpace(aNclx, [&]() {
+ MOZ_LOG(sAVIFLog, LogLevel::Info,
+ ("YUVColorSpace cannot be determined from colr box, using AV1 "
+ "sequence header"));
+ return DAV1DDecoder::GetColorSpace(*aPicture, sAVIFLog);
+ });
+
+ auto av1ColourPrimaries = CICP::ColourPrimaries::CP_UNSPECIFIED;
+ auto av1TransferCharacteristics =
+ CICP::TransferCharacteristics::TC_UNSPECIFIED;
+ auto av1MatrixCoefficients = CICP::MatrixCoefficients::MC_UNSPECIFIED;
+
+ MOZ_ASSERT(aPicture->seq_hdr);
+ auto& seq_hdr = *aPicture->seq_hdr;
+
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("seq_hdr.color_description_present: %d",
+ seq_hdr.color_description_present));
+ if (seq_hdr.color_description_present) {
+ av1ColourPrimaries = static_cast<CICP::ColourPrimaries>(seq_hdr.pri);
+ av1TransferCharacteristics =
+ static_cast<CICP::TransferCharacteristics>(seq_hdr.trc);
+ av1MatrixCoefficients = static_cast<CICP::MatrixCoefficients>(seq_hdr.mtrx);
+ }
+
+ data->SetCicpValues(aNclx, av1ColourPrimaries, av1TransferCharacteristics,
+ av1MatrixCoefficients);
+
+ gfx::ColorRange av1ColorRange =
+ seq_hdr.color_range ? gfx::ColorRange::FULL : gfx::ColorRange::LIMITED;
+ data->mColorRange = GetAVIFColorRange(aNclx, av1ColorRange);
+
+ auto colorPrimaries =
+ gfxUtils::CicpToColorPrimaries(data->mColourPrimaries, sAVIFLog);
+ if (colorPrimaries.isSome()) {
+ data->mColorPrimaries = *colorPrimaries;
+ }
+
+ if (aAlphaPlane) {
+ MOZ_ASSERT(aAlphaPlane->stride[0] == data->mYStride);
+ data->mAlpha.emplace();
+ data->mAlpha->mChannel = static_cast<uint8_t*>(aAlphaPlane->data[0]);
+ data->mAlpha->mSize = gfx::IntSize(aAlphaPlane->p.w, aAlphaPlane->p.h);
+ data->mAlpha->mPremultiplied = aPremultipliedAlpha;
+ }
+
+ data->mColorDav1d = std::move(aPicture);
+ data->mAlphaDav1d = std::move(aAlphaPlane);
+
+ return data;
+}
+
+/* static */
+UniquePtr<AVIFDecodedData> AOMDecoder::AOMImageToToDecodedData(
+ const Mp4parseNclxColourInformation* aNclx, UniquePtr<OwnedAOMImage> aImage,
+ UniquePtr<OwnedAOMImage> aAlphaPlane, bool aPremultipliedAlpha) {
+ aom_image_t* colorImage = aImage->GetImage();
+ aom_image_t* alphaImage = aAlphaPlane ? aAlphaPlane->GetImage() : nullptr;
+
+ MOZ_ASSERT(colorImage);
+ MOZ_ASSERT(colorImage->stride[AOM_PLANE_Y] ==
+ colorImage->stride[AOM_PLANE_ALPHA]);
+ MOZ_ASSERT(colorImage->stride[AOM_PLANE_Y] >=
+ aom_img_plane_width(colorImage, AOM_PLANE_Y));
+ MOZ_ASSERT(colorImage->stride[AOM_PLANE_U] ==
+ colorImage->stride[AOM_PLANE_V]);
+ MOZ_ASSERT(colorImage->stride[AOM_PLANE_U] >=
+ aom_img_plane_width(colorImage, AOM_PLANE_U));
+ MOZ_ASSERT(colorImage->stride[AOM_PLANE_V] >=
+ aom_img_plane_width(colorImage, AOM_PLANE_V));
+ MOZ_ASSERT(aom_img_plane_width(colorImage, AOM_PLANE_U) ==
+ aom_img_plane_width(colorImage, AOM_PLANE_V));
+ MOZ_ASSERT(aom_img_plane_height(colorImage, AOM_PLANE_U) ==
+ aom_img_plane_height(colorImage, AOM_PLANE_V));
+
+ UniquePtr<AVIFDecodedData> data = MakeUnique<AVIFDecodedData>();
+
+ data->mRenderSize.emplace(colorImage->r_w, colorImage->r_h);
+
+ data->mYChannel = colorImage->planes[AOM_PLANE_Y];
+ data->mYStride = colorImage->stride[AOM_PLANE_Y];
+ data->mYSkip = colorImage->stride[AOM_PLANE_Y] -
+ aom_img_plane_width(colorImage, AOM_PLANE_Y);
+ data->mCbChannel = colorImage->planes[AOM_PLANE_U];
+ data->mCrChannel = colorImage->planes[AOM_PLANE_V];
+ data->mCbCrStride = colorImage->stride[AOM_PLANE_U];
+ data->mCbSkip = colorImage->stride[AOM_PLANE_U] -
+ aom_img_plane_width(colorImage, AOM_PLANE_U);
+ data->mCrSkip = colorImage->stride[AOM_PLANE_V] -
+ aom_img_plane_width(colorImage, AOM_PLANE_V);
+ data->mPictureRect = gfx::IntRect(0, 0, colorImage->d_w, colorImage->d_h);
+ data->mStereoMode = StereoMode::MONO;
+ data->mColorDepth = ColorDepthForBitDepth(colorImage->bit_depth);
+
+ if (colorImage->x_chroma_shift == 1 && colorImage->y_chroma_shift == 1) {
+ data->mChromaSubsampling = gfx::ChromaSubsampling::HALF_WIDTH_AND_HEIGHT;
+ } else if (colorImage->x_chroma_shift == 1 &&
+ colorImage->y_chroma_shift == 0) {
+ data->mChromaSubsampling = gfx::ChromaSubsampling::HALF_WIDTH;
+ } else if (colorImage->x_chroma_shift != 0 ||
+ colorImage->y_chroma_shift != 0) {
+ MOZ_ASSERT_UNREACHABLE("unexpected chroma shifts");
+ }
+
+ MOZ_ASSERT(colorImage->bit_depth == BitDepthForColorDepth(data->mColorDepth));
+
+ auto av1ColourPrimaries = static_cast<CICP::ColourPrimaries>(colorImage->cp);
+ auto av1TransferCharacteristics =
+ static_cast<CICP::TransferCharacteristics>(colorImage->tc);
+ auto av1MatrixCoefficients =
+ static_cast<CICP::MatrixCoefficients>(colorImage->mc);
+
+ data->mYUVColorSpace = GetAVIFColorSpace(aNclx, [=]() {
+ MOZ_LOG(sAVIFLog, LogLevel::Info,
+ ("YUVColorSpace cannot be determined from colr box, using AV1 "
+ "sequence header"));
+ return gfxUtils::CicpToColorSpace(av1MatrixCoefficients, av1ColourPrimaries,
+ sAVIFLog);
+ });
+
+ gfx::ColorRange av1ColorRange;
+ if (colorImage->range == AOM_CR_STUDIO_RANGE) {
+ av1ColorRange = gfx::ColorRange::LIMITED;
+ } else {
+ MOZ_ASSERT(colorImage->range == AOM_CR_FULL_RANGE);
+ av1ColorRange = gfx::ColorRange::FULL;
+ }
+ data->mColorRange = GetAVIFColorRange(aNclx, av1ColorRange);
+
+ data->SetCicpValues(aNclx, av1ColourPrimaries, av1TransferCharacteristics,
+ av1MatrixCoefficients);
+
+ auto colorPrimaries =
+ gfxUtils::CicpToColorPrimaries(data->mColourPrimaries, sAVIFLog);
+ if (colorPrimaries.isSome()) {
+ data->mColorPrimaries = *colorPrimaries;
+ }
+
+ if (alphaImage) {
+ MOZ_ASSERT(alphaImage->stride[AOM_PLANE_Y] == data->mYStride);
+ data->mAlpha.emplace();
+ data->mAlpha->mChannel = alphaImage->planes[AOM_PLANE_Y];
+ data->mAlpha->mSize = gfx::IntSize(alphaImage->d_w, alphaImage->d_h);
+ data->mAlpha->mPremultiplied = aPremultipliedAlpha;
+ }
+
+ data->mColorAOM = std::move(aImage);
+ data->mAlphaAOM = std::move(aAlphaPlane);
+
+ return data;
+}
+
+// Wrapper to allow rust to call our read adaptor.
+intptr_t nsAVIFDecoder::ReadSource(uint8_t* aDestBuf, uintptr_t aDestBufSize,
+ void* aUserData) {
+ MOZ_ASSERT(aDestBuf);
+ MOZ_ASSERT(aUserData);
+
+ MOZ_LOG(sAVIFLog, LogLevel::Verbose,
+ ("AVIF ReadSource, aDestBufSize: %zu", aDestBufSize));
+
+ auto* decoder = reinterpret_cast<nsAVIFDecoder*>(aUserData);
+
+ MOZ_ASSERT(decoder->mReadCursor);
+
+ size_t bufferLength = decoder->mBufferedData.end() - decoder->mReadCursor;
+ size_t n_bytes = std::min(aDestBufSize, bufferLength);
+
+ MOZ_LOG(
+ sAVIFLog, LogLevel::Verbose,
+ ("AVIF ReadSource, %zu bytes ready, copying %zu", bufferLength, n_bytes));
+
+ memcpy(aDestBuf, decoder->mReadCursor, n_bytes);
+ decoder->mReadCursor += n_bytes;
+
+ return n_bytes;
+}
+
+nsAVIFDecoder::nsAVIFDecoder(RasterImage* aImage) : Decoder(aImage) {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] nsAVIFDecoder::nsAVIFDecoder", this));
+}
+
+nsAVIFDecoder::~nsAVIFDecoder() {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] nsAVIFDecoder::~nsAVIFDecoder", this));
+}
+
+LexerResult nsAVIFDecoder::DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) {
+ MOZ_LOG(sAVIFLog, LogLevel::Info,
+ ("[this=%p] nsAVIFDecoder::DoDecode start", this));
+
+ DecodeResult result = DoDecodeInternal(aIterator, aOnResume);
+
+ RecordDecodeResultTelemetry(result);
+
+ if (result.is<NonDecoderResult>()) {
+ NonDecoderResult r = result.as<NonDecoderResult>();
+ if (r == NonDecoderResult::NeedMoreData) {
+ return LexerResult(Yield::NEED_MORE_DATA);
+ }
+ if (r == NonDecoderResult::OutputAvailable) {
+ MOZ_ASSERT(HasSize());
+ return LexerResult(Yield::OUTPUT_AVAILABLE);
+ }
+ if (r == NonDecoderResult::Complete) {
+ MOZ_ASSERT(HasSize());
+ return LexerResult(TerminalState::SUCCESS);
+ }
+ return LexerResult(TerminalState::FAILURE);
+ }
+
+ MOZ_ASSERT(result.is<Dav1dResult>() || result.is<AOMResult>() ||
+ result.is<Mp4parseStatus>());
+ // If IsMetadataDecode(), a successful parse should return
+ // NonDecoderResult::MetadataOk or else continue to the decode stage
+ MOZ_ASSERT_IF(result.is<Mp4parseStatus>(),
+ result.as<Mp4parseStatus>() != MP4PARSE_STATUS_OK);
+ auto rv = LexerResult(IsDecodeSuccess(result) ? TerminalState::SUCCESS
+ : TerminalState::FAILURE);
+ MOZ_LOG(sAVIFLog, LogLevel::Info,
+ ("[this=%p] nsAVIFDecoder::DoDecode end", this));
+ return rv;
+}
+
+Mp4parseStatus nsAVIFDecoder::CreateParser() {
+ if (!mParser) {
+ Mp4parseIo io = {nsAVIFDecoder::ReadSource, this};
+ mBufferStream = new AVIFDecoderStream(&mBufferedData);
+
+ Mp4parseStatus status = AVIFParser::Create(
+ &io, mBufferStream.get(), mParser,
+ bool(GetDecoderFlags() & DecoderFlags::AVIF_SEQUENCES_ENABLED),
+ bool(GetDecoderFlags() & DecoderFlags::AVIF_ANIMATE_AVIF_MAJOR));
+
+ if (status != MP4PARSE_STATUS_OK) {
+ return status;
+ }
+
+ const Mp4parseAvifInfo& info = mParser->GetInfo();
+ mIsAnimated = mParser->IsAnimated();
+ mHasAlpha = mIsAnimated ? !!info.alpha_track_id : info.has_alpha_item;
+ }
+
+ return MP4PARSE_STATUS_OK;
+}
+
+nsAVIFDecoder::DecodeResult nsAVIFDecoder::CreateDecoder() {
+ if (!mDecoder) {
+ DecodeResult r = StaticPrefs::image_avif_use_dav1d()
+ ? Dav1dDecoder::Create(mDecoder, mHasAlpha)
+ : AOMDecoder::Create(mDecoder, mHasAlpha);
+
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] Create %sDecoder %ssuccessfully", this,
+ StaticPrefs::image_avif_use_dav1d() ? "Dav1d" : "AOM",
+ IsDecodeSuccess(r) ? "" : "un"));
+
+ return r;
+ }
+
+ return StaticPrefs::image_avif_use_dav1d()
+ ? DecodeResult(Dav1dResult(0))
+ : DecodeResult(AOMResult(AOM_CODEC_OK));
+}
+
+// Records all telemetry available in the AVIF metadata, called only once during
+// the metadata decode to avoid multiple counts.
+static void RecordMetadataTelem(const Mp4parseAvifInfo& aInfo) {
+ if (aInfo.pixel_aspect_ratio) {
+ const uint32_t& h_spacing = aInfo.pixel_aspect_ratio->h_spacing;
+ const uint32_t& v_spacing = aInfo.pixel_aspect_ratio->v_spacing;
+
+ if (h_spacing == 0 || v_spacing == 0) {
+ AccumulateCategorical(LABELS_AVIF_PASP::invalid);
+ } else if (h_spacing == v_spacing) {
+ AccumulateCategorical(LABELS_AVIF_PASP::square);
+ } else {
+ AccumulateCategorical(LABELS_AVIF_PASP::nonsquare);
+ }
+ } else {
+ AccumulateCategorical(LABELS_AVIF_PASP::absent);
+ }
+
+ const auto& major_brand = aInfo.major_brand;
+ if (!memcmp(major_brand, "avif", sizeof(major_brand))) {
+ AccumulateCategorical(LABELS_AVIF_MAJOR_BRAND::avif);
+ } else if (!memcmp(major_brand, "avis", sizeof(major_brand))) {
+ AccumulateCategorical(LABELS_AVIF_MAJOR_BRAND::avis);
+ } else {
+ AccumulateCategorical(LABELS_AVIF_MAJOR_BRAND::other);
+ }
+
+ AccumulateCategorical(aInfo.has_sequence ? LABELS_AVIF_SEQUENCE::present
+ : LABELS_AVIF_SEQUENCE::absent);
+
+#define FEATURE_TELEMETRY(fourcc) \
+ AccumulateCategorical( \
+ (aInfo.unsupported_features_bitfield & (1 << MP4PARSE_FEATURE_##fourcc)) \
+ ? LABELS_AVIF_##fourcc::present \
+ : LABELS_AVIF_##fourcc::absent)
+ FEATURE_TELEMETRY(A1LX);
+ FEATURE_TELEMETRY(A1OP);
+ FEATURE_TELEMETRY(CLAP);
+ FEATURE_TELEMETRY(GRID);
+ FEATURE_TELEMETRY(IPRO);
+ FEATURE_TELEMETRY(LSEL);
+
+ if (aInfo.nclx_colour_information && aInfo.icc_colour_information.data) {
+ AccumulateCategorical(LABELS_AVIF_COLR::both);
+ } else if (aInfo.nclx_colour_information) {
+ AccumulateCategorical(LABELS_AVIF_COLR::nclx);
+ } else if (aInfo.icc_colour_information.data) {
+ AccumulateCategorical(LABELS_AVIF_COLR::icc);
+ } else {
+ AccumulateCategorical(LABELS_AVIF_COLR::absent);
+ }
+}
+
+static void RecordPixiTelemetry(uint8_t aPixiBitDepth,
+ uint8_t aBitstreamBitDepth,
+ const char* aItemName) {
+ if (aPixiBitDepth == 0) {
+ AccumulateCategorical(LABELS_AVIF_PIXI::absent);
+ } else if (aPixiBitDepth == aBitstreamBitDepth) {
+ AccumulateCategorical(LABELS_AVIF_PIXI::valid);
+ } else {
+ MOZ_LOG(sAVIFLog, LogLevel::Error,
+ ("%s item pixi bit depth (%hhu) doesn't match "
+ "bitstream (%hhu)",
+ aItemName, aPixiBitDepth, aBitstreamBitDepth));
+ AccumulateCategorical(LABELS_AVIF_PIXI::bitstream_mismatch);
+ }
+}
+
+// This telemetry depends on the results of decoding.
+// These data must be recorded only on the first frame decoded after metadata
+// decode finishes.
+static void RecordFrameTelem(bool aAnimated, const Mp4parseAvifInfo& aInfo,
+ const AVIFDecodedData& aData) {
+ AccumulateCategorical(
+ gColorSpaceLabel[static_cast<size_t>(aData.mYUVColorSpace)]);
+ AccumulateCategorical(
+ gColorDepthLabel[static_cast<size_t>(aData.mColorDepth)]);
+
+ RecordPixiTelemetry(
+ aAnimated ? aInfo.color_track_bit_depth : aInfo.primary_item_bit_depth,
+ BitDepthForColorDepth(aData.mColorDepth), "color");
+
+ if (aData.mAlpha) {
+ AccumulateCategorical(LABELS_AVIF_ALPHA::present);
+ RecordPixiTelemetry(
+ aAnimated ? aInfo.alpha_track_bit_depth : aInfo.alpha_item_bit_depth,
+ BitDepthForColorDepth(aData.mColorDepth), "alpha");
+ } else {
+ AccumulateCategorical(LABELS_AVIF_ALPHA::absent);
+ }
+
+ if (CICP::IsReserved(aData.mColourPrimaries)) {
+ AccumulateCategorical(LABELS_AVIF_CICP_CP::RESERVED_REST);
+ } else {
+ AccumulateCategorical(
+ static_cast<LABELS_AVIF_CICP_CP>(aData.mColourPrimaries));
+ }
+
+ if (CICP::IsReserved(aData.mTransferCharacteristics)) {
+ AccumulateCategorical(LABELS_AVIF_CICP_TC::RESERVED);
+ } else {
+ AccumulateCategorical(
+ static_cast<LABELS_AVIF_CICP_TC>(aData.mTransferCharacteristics));
+ }
+
+ if (CICP::IsReserved(aData.mMatrixCoefficients)) {
+ AccumulateCategorical(LABELS_AVIF_CICP_MC::RESERVED);
+ } else {
+ AccumulateCategorical(
+ static_cast<LABELS_AVIF_CICP_MC>(aData.mMatrixCoefficients));
+ }
+}
+
+nsAVIFDecoder::DecodeResult nsAVIFDecoder::DoDecodeInternal(
+ SourceBufferIterator& aIterator, IResumable* aOnResume) {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] nsAVIFDecoder::DoDecodeInternal", this));
+
+ // Since the SourceBufferIterator doesn't guarantee a contiguous buffer,
+ // but the current mp4parse-rust implementation requires it, always buffer
+ // locally. This keeps the code simpler at the cost of some performance, but
+ // this implementation is only experimental, so we don't want to spend time
+ // optimizing it prematurely.
+ while (!mReadCursor) {
+ SourceBufferIterator::State state =
+ aIterator.AdvanceOrScheduleResume(SIZE_MAX, aOnResume);
+
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] After advance, iterator state is %d", this, state));
+
+ switch (state) {
+ case SourceBufferIterator::WAITING:
+ return AsVariant(NonDecoderResult::NeedMoreData);
+
+ case SourceBufferIterator::COMPLETE:
+ mReadCursor = mBufferedData.begin();
+ break;
+
+ case SourceBufferIterator::READY: { // copy new data to buffer
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] SourceBufferIterator ready, %zu bytes available",
+ this, aIterator.Length()));
+
+ bool appendSuccess =
+ mBufferedData.append(aIterator.Data(), aIterator.Length());
+
+ if (!appendSuccess) {
+ MOZ_LOG(sAVIFLog, LogLevel::Error,
+ ("[this=%p] Failed to append %zu bytes to buffer", this,
+ aIterator.Length()));
+ }
+
+ break;
+ }
+
+ default:
+ MOZ_ASSERT_UNREACHABLE("unexpected SourceBufferIterator state");
+ }
+ }
+
+ Mp4parseStatus parserStatus = CreateParser();
+
+ if (parserStatus != MP4PARSE_STATUS_OK) {
+ return AsVariant(parserStatus);
+ }
+
+ const Mp4parseAvifInfo& parsedInfo = mParser->GetInfo();
+
+ if (parsedInfo.icc_colour_information.data) {
+ const auto& icc = parsedInfo.icc_colour_information;
+ MOZ_LOG(
+ sAVIFLog, LogLevel::Debug,
+ ("[this=%p] colr type ICC: %zu bytes %p", this, icc.length, icc.data));
+ }
+
+ if (IsMetadataDecode()) {
+ RecordMetadataTelem(parsedInfo);
+ }
+
+ if (parsedInfo.nclx_colour_information) {
+ const auto& nclx = *parsedInfo.nclx_colour_information;
+ MOZ_LOG(
+ sAVIFLog, LogLevel::Debug,
+ ("[this=%p] colr type CICP: cp/tc/mc/full-range %u/%u/%u/%s", this,
+ nclx.colour_primaries, nclx.transfer_characteristics,
+ nclx.matrix_coefficients, nclx.full_range_flag ? "true" : "false"));
+ }
+
+ if (!parsedInfo.icc_colour_information.data &&
+ !parsedInfo.nclx_colour_information) {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] colr box not present", this));
+ }
+
+ AVIFImage parsedImage;
+ DecodeResult r = mParser->GetImage(parsedImage);
+ if (!IsDecodeSuccess(r)) {
+ return r;
+ }
+ bool isDone =
+ !IsMetadataDecode() && r == DecodeResult(NonDecoderResult::Complete);
+
+ if (mIsAnimated) {
+ PostIsAnimated(parsedImage.mDuration);
+ }
+ if (mHasAlpha) {
+ PostHasTransparency();
+ }
+
+ Orientation orientation = StaticPrefs::image_avif_apply_transforms()
+ ? GetImageOrientation(parsedInfo)
+ : Orientation{};
+ // TODO: Orientation should probably also apply to animated AVIFs.
+ if (mIsAnimated) {
+ orientation = Orientation{};
+ }
+
+ MaybeIntSize ispeImageSize = GetImageSize(parsedInfo);
+
+ bool sendDecodeTelemetry = IsMetadataDecode();
+ if (ispeImageSize.isSome()) {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] Parser returned image size %d x %d (%d/%d bit)", this,
+ ispeImageSize->width, ispeImageSize->height,
+ mIsAnimated ? parsedInfo.color_track_bit_depth
+ : parsedInfo.primary_item_bit_depth,
+ mIsAnimated ? parsedInfo.alpha_track_bit_depth
+ : parsedInfo.alpha_item_bit_depth));
+ PostSize(ispeImageSize->width, ispeImageSize->height, orientation);
+ if (IsMetadataDecode()) {
+ MOZ_LOG(
+ sAVIFLog, LogLevel::Debug,
+ ("[this=%p] Finishing metadata decode without image decode", this));
+ return AsVariant(NonDecoderResult::Complete);
+ }
+ // If we're continuing to decode here, this means we skipped decode
+ // telemetry for the metadata decode pass. Send it this time.
+ sendDecodeTelemetry = true;
+ } else {
+ MOZ_LOG(sAVIFLog, LogLevel::Error,
+ ("[this=%p] Parser returned no image size, decoding...", this));
+ }
+
+ r = CreateDecoder();
+ if (!IsDecodeSuccess(r)) {
+ return r;
+ }
+ MOZ_ASSERT(mDecoder);
+ r = mDecoder->Decode(sendDecodeTelemetry, parsedInfo, parsedImage);
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] Decoder%s->Decode() %s", this,
+ StaticPrefs::image_avif_use_dav1d() ? "Dav1d" : "AOM",
+ IsDecodeSuccess(r) ? "succeeds" : "fails"));
+
+ if (!IsDecodeSuccess(r)) {
+ return r;
+ }
+
+ UniquePtr<AVIFDecodedData> decodedData = mDecoder->GetDecodedData();
+
+ MOZ_ASSERT_IF(mHasAlpha, decodedData->mAlpha.isSome());
+
+ MOZ_ASSERT(decodedData->mColourPrimaries !=
+ CICP::ColourPrimaries::CP_UNSPECIFIED);
+ MOZ_ASSERT(decodedData->mTransferCharacteristics !=
+ CICP::TransferCharacteristics::TC_UNSPECIFIED);
+ MOZ_ASSERT(decodedData->mColorRange <= gfx::ColorRange::_Last);
+ MOZ_ASSERT(decodedData->mYUVColorSpace <= gfx::YUVColorSpace::_Last);
+
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] decodedData.mColorRange: %hhd", this,
+ static_cast<uint8_t>(decodedData->mColorRange)));
+
+ // Technically it's valid but we don't handle it now (Bug 1682318).
+ if (decodedData->mAlpha &&
+ decodedData->mAlpha->mSize != decodedData->YDataSize()) {
+ return AsVariant(NonDecoderResult::AlphaYSizeMismatch);
+ }
+
+ bool isFirstFrame = GetFrameCount() == 0;
+
+ if (!HasSize()) {
+ MOZ_ASSERT(isFirstFrame);
+ MOZ_LOG(
+ sAVIFLog, LogLevel::Error,
+ ("[this=%p] Using decoded image size: %d x %d", this,
+ decodedData->mPictureRect.width, decodedData->mPictureRect.height));
+ PostSize(decodedData->mPictureRect.width, decodedData->mPictureRect.height,
+ orientation);
+ AccumulateCategorical(LABELS_AVIF_ISPE::absent);
+ } else {
+ // Verify that the bitstream hasn't changed the image size compared to
+ // either the ispe box or the previous frames.
+ IntSize expectedSize = GetImageMetadata()
+ .GetOrientation()
+ .ToUnoriented(Size())
+ .ToUnknownSize();
+ if (decodedData->mPictureRect.width != expectedSize.width ||
+ decodedData->mPictureRect.height != expectedSize.height) {
+ if (isFirstFrame) {
+ MOZ_LOG(
+ sAVIFLog, LogLevel::Error,
+ ("[this=%p] Metadata image size doesn't match decoded image size: "
+ "(%d x %d) != (%d x %d)",
+ this, ispeImageSize->width, ispeImageSize->height,
+ decodedData->mPictureRect.width,
+ decodedData->mPictureRect.height));
+ AccumulateCategorical(LABELS_AVIF_ISPE::bitstream_mismatch);
+ return AsVariant(NonDecoderResult::MetadataImageSizeMismatch);
+ }
+
+ MOZ_LOG(
+ sAVIFLog, LogLevel::Error,
+ ("[this=%p] Frame size has changed in the bitstream: "
+ "(%d x %d) != (%d x %d)",
+ this, expectedSize.width, expectedSize.height,
+ decodedData->mPictureRect.width, decodedData->mPictureRect.height));
+ return AsVariant(NonDecoderResult::FrameSizeChanged);
+ }
+
+ if (isFirstFrame) {
+ AccumulateCategorical(LABELS_AVIF_ISPE::valid);
+ }
+ }
+
+ if (IsMetadataDecode()) {
+ return AsVariant(NonDecoderResult::Complete);
+ }
+
+ IntSize rgbSize = decodedData->mPictureRect.Size();
+
+ if (parsedImage.mFrameNum == 0) {
+ RecordFrameTelem(mIsAnimated, parsedInfo, *decodedData);
+ }
+
+ if (decodedData->mRenderSize &&
+ decodedData->mRenderSize->ToUnknownSize() != rgbSize) {
+ // This may be supported by allowing all metadata decodes to decode a frame
+ // and get the render size from the bitstream. However it's unlikely to be
+ // used often.
+ return AsVariant(NonDecoderResult::RenderSizeMismatch);
+ }
+
+ // Read color profile
+ if (mCMSMode != CMSMode::Off) {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] Processing color profile", this));
+
+ // See comment on AVIFDecodedData
+ if (parsedInfo.icc_colour_information.data) {
+ // same profile for every frame of image, only create it once
+ if (!mInProfile) {
+ const auto& icc = parsedInfo.icc_colour_information;
+ mInProfile = qcms_profile_from_memory(icc.data, icc.length);
+ }
+ } else {
+ // potentially different profile every frame, destroy the old one
+ if (mInProfile) {
+ if (mTransform) {
+ qcms_transform_release(mTransform);
+ mTransform = nullptr;
+ }
+ qcms_profile_release(mInProfile);
+ mInProfile = nullptr;
+ }
+
+ const auto& cp = decodedData->mColourPrimaries;
+ const auto& tc = decodedData->mTransferCharacteristics;
+
+ if (CICP::IsReserved(cp)) {
+ MOZ_LOG(sAVIFLog, LogLevel::Error,
+ ("[this=%p] colour_primaries reserved value (%hhu) is invalid; "
+ "failing",
+ this, cp));
+ return AsVariant(NonDecoderResult::InvalidCICP);
+ }
+
+ if (CICP::IsReserved(tc)) {
+ MOZ_LOG(sAVIFLog, LogLevel::Error,
+ ("[this=%p] transfer_characteristics reserved value (%hhu) is "
+ "invalid; failing",
+ this, tc));
+ return AsVariant(NonDecoderResult::InvalidCICP);
+ }
+
+ MOZ_ASSERT(cp != CICP::ColourPrimaries::CP_UNSPECIFIED &&
+ !CICP::IsReserved(cp));
+ MOZ_ASSERT(tc != CICP::TransferCharacteristics::TC_UNSPECIFIED &&
+ !CICP::IsReserved(tc));
+
+ mInProfile = qcms_profile_create_cicp(cp, tc);
+ }
+
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] mInProfile %p", this, mInProfile));
+ } else {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] CMSMode::Off, skipping color profile", this));
+ }
+
+ if (mInProfile && GetCMSOutputProfile() && !mTransform) {
+ auto intent = static_cast<qcms_intent>(gfxPlatform::GetRenderingIntent());
+ qcms_data_type inType;
+ qcms_data_type outType;
+
+ // If we're not mandating an intent, use the one from the image.
+ if (gfxPlatform::GetRenderingIntent() == -1) {
+ intent = qcms_profile_get_rendering_intent(mInProfile);
+ }
+
+ uint32_t profileSpace = qcms_profile_get_color_space(mInProfile);
+ if (profileSpace != icSigGrayData) {
+ // If the transform happens with SurfacePipe, it will be in RGBA if we
+ // have an alpha channel, because the swizzle and premultiplication
+ // happens after color management. Otherwise it will be in BGRA because
+ // the swizzle happens at the start.
+ if (mHasAlpha) {
+ inType = QCMS_DATA_RGBA_8;
+ outType = QCMS_DATA_RGBA_8;
+ } else {
+ inType = gfxPlatform::GetCMSOSRGBAType();
+ outType = inType;
+ }
+ } else {
+ if (mHasAlpha) {
+ inType = QCMS_DATA_GRAYA_8;
+ outType = gfxPlatform::GetCMSOSRGBAType();
+ } else {
+ inType = QCMS_DATA_GRAY_8;
+ outType = gfxPlatform::GetCMSOSRGBAType();
+ }
+ }
+
+ mTransform = qcms_transform_create(mInProfile, inType,
+ GetCMSOutputProfile(), outType, intent);
+ }
+
+ // Get suggested format and size. Note that GetYCbCrToRGBDestFormatAndSize
+ // force format to be B8G8R8X8 if it's not.
+ gfx::SurfaceFormat format = SurfaceFormat::OS_RGBX;
+ gfx::GetYCbCrToRGBDestFormatAndSize(*decodedData, format, rgbSize);
+ if (mHasAlpha) {
+ // We would use libyuv to do the YCbCrA -> ARGB convertion, which only
+ // works for B8G8R8A8.
+ format = SurfaceFormat::B8G8R8A8;
+ }
+
+ const int bytesPerPixel = BytesPerPixel(format);
+
+ const CheckedInt rgbStride = CheckedInt<int>(rgbSize.width) * bytesPerPixel;
+ const CheckedInt rgbBufLength = rgbStride * rgbSize.height;
+
+ if (!rgbStride.isValid() || !rgbBufLength.isValid()) {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] overflow calculating rgbBufLength: rbgSize.width: %d, "
+ "rgbSize.height: %d, "
+ "bytesPerPixel: %u",
+ this, rgbSize.width, rgbSize.height, bytesPerPixel));
+ return AsVariant(NonDecoderResult::SizeOverflow);
+ }
+
+ UniquePtr<uint8_t[]> rgbBuf =
+ MakeUniqueFallible<uint8_t[]>(rgbBufLength.value());
+ if (!rgbBuf) {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] allocation of %u-byte rgbBuf failed", this,
+ rgbBufLength.value()));
+ return AsVariant(NonDecoderResult::OutOfMemory);
+ }
+
+ if (decodedData->mAlpha) {
+ const auto wantPremultiply =
+ !bool(GetSurfaceFlags() & SurfaceFlags::NO_PREMULTIPLY_ALPHA);
+ const bool& hasPremultiply = decodedData->mAlpha->mPremultiplied;
+
+ PremultFunc premultOp = nullptr;
+ if (wantPremultiply && !hasPremultiply) {
+ premultOp = libyuv::ARGBAttenuate;
+ } else if (!wantPremultiply && hasPremultiply) {
+ premultOp = libyuv::ARGBUnattenuate;
+ }
+
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] calling gfx::ConvertYCbCrAToARGB premultOp: %p", this,
+ premultOp));
+ gfx::ConvertYCbCrAToARGB(*decodedData, *decodedData->mAlpha, format,
+ rgbSize, rgbBuf.get(), rgbStride.value(),
+ premultOp);
+ } else {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] calling gfx::ConvertYCbCrToRGB", this));
+ gfx::ConvertYCbCrToRGB(*decodedData, format, rgbSize, rgbBuf.get(),
+ rgbStride.value());
+ }
+
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] calling SurfacePipeFactory::CreateSurfacePipe", this));
+
+ Maybe<SurfacePipe> pipe = Nothing();
+
+ if (mIsAnimated) {
+ SurfaceFormat outFormat =
+ decodedData->mAlpha ? SurfaceFormat::OS_RGBA : SurfaceFormat::OS_RGBX;
+ Maybe<AnimationParams> animParams;
+ if (!IsFirstFrameDecode()) {
+ animParams.emplace(FullFrame().ToUnknownRect(), parsedImage.mDuration,
+ parsedImage.mFrameNum, BlendMethod::SOURCE,
+ DisposalMethod::CLEAR_ALL);
+ }
+ pipe = SurfacePipeFactory::CreateSurfacePipe(
+ this, Size(), OutputSize(), FullFrame(), format, outFormat, animParams,
+ mTransform, SurfacePipeFlags());
+ } else {
+ pipe = SurfacePipeFactory::CreateReorientSurfacePipe(
+ this, Size(), OutputSize(), format, mTransform, GetOrientation());
+ }
+
+ if (pipe.isNothing()) {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] could not initialize surface pipe", this));
+ return AsVariant(NonDecoderResult::PipeInitError);
+ }
+
+ MOZ_LOG(sAVIFLog, LogLevel::Debug, ("[this=%p] writing to surface", this));
+ const uint8_t* endOfRgbBuf = {rgbBuf.get() + rgbBufLength.value()};
+ WriteState writeBufferResult = WriteState::NEED_MORE_DATA;
+ for (uint8_t* rowPtr = rgbBuf.get(); rowPtr < endOfRgbBuf;
+ rowPtr += rgbStride.value()) {
+ writeBufferResult = pipe->WriteBuffer(reinterpret_cast<uint32_t*>(rowPtr));
+
+ Maybe<SurfaceInvalidRect> invalidRect = pipe->TakeInvalidRect();
+ if (invalidRect) {
+ PostInvalidation(invalidRect->mInputSpaceRect,
+ Some(invalidRect->mOutputSpaceRect));
+ }
+
+ if (writeBufferResult == WriteState::FAILURE) {
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] error writing rowPtr to surface pipe", this));
+
+ } else if (writeBufferResult == WriteState::FINISHED) {
+ MOZ_ASSERT(rowPtr + rgbStride.value() == endOfRgbBuf);
+ }
+ }
+
+ MOZ_LOG(sAVIFLog, LogLevel::Debug,
+ ("[this=%p] writing to surface complete", this));
+
+ if (writeBufferResult == WriteState::FINISHED) {
+ PostFrameStop(mHasAlpha ? Opacity::SOME_TRANSPARENCY
+ : Opacity::FULLY_OPAQUE);
+
+ if (!mIsAnimated || IsFirstFrameDecode()) {
+ PostDecodeDone(0);
+ return DecodeResult(NonDecoderResult::Complete);
+ }
+
+ if (isDone) {
+ switch (mParser->GetInfo().loop_mode) {
+ case MP4PARSE_AVIF_LOOP_MODE_LOOP_BY_COUNT: {
+ auto loopCount = mParser->GetInfo().loop_count;
+ PostDecodeDone(
+ loopCount > INT32_MAX ? -1 : static_cast<int32_t>(loopCount));
+ break;
+ }
+ case MP4PARSE_AVIF_LOOP_MODE_LOOP_INFINITELY:
+ case MP4PARSE_AVIF_LOOP_MODE_NO_EDITS:
+ default:
+ PostDecodeDone(-1);
+ break;
+ }
+ return DecodeResult(NonDecoderResult::Complete);
+ }
+
+ return DecodeResult(NonDecoderResult::OutputAvailable);
+ }
+
+ return AsVariant(NonDecoderResult::WriteBufferError);
+}
+
+/* static */
+bool nsAVIFDecoder::IsDecodeSuccess(const DecodeResult& aResult) {
+ return aResult == DecodeResult(NonDecoderResult::OutputAvailable) ||
+ aResult == DecodeResult(NonDecoderResult::Complete) ||
+ aResult == DecodeResult(Dav1dResult(0)) ||
+ aResult == DecodeResult(AOMResult(AOM_CODEC_OK));
+}
+
+void nsAVIFDecoder::RecordDecodeResultTelemetry(
+ const nsAVIFDecoder::DecodeResult& aResult) {
+ if (aResult.is<Mp4parseStatus>()) {
+ switch (aResult.as<Mp4parseStatus>()) {
+ case MP4PARSE_STATUS_OK:
+ MOZ_ASSERT_UNREACHABLE(
+ "Expect NonDecoderResult, Dav1dResult or AOMResult");
+ return;
+ case MP4PARSE_STATUS_BAD_ARG:
+ case MP4PARSE_STATUS_INVALID:
+ case MP4PARSE_STATUS_UNSUPPORTED:
+ case MP4PARSE_STATUS_EOF:
+ case MP4PARSE_STATUS_IO:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::parse_error);
+ return;
+ case MP4PARSE_STATUS_OOM:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::out_of_memory);
+ return;
+ case MP4PARSE_STATUS_MISSING_AVIF_OR_AVIS_BRAND:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::missing_brand);
+ return;
+ case MP4PARSE_STATUS_FTYP_NOT_FIRST:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::ftyp_not_first);
+ return;
+ case MP4PARSE_STATUS_NO_IMAGE:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::no_image);
+ return;
+ case MP4PARSE_STATUS_MOOV_BAD_QUANTITY:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::multiple_moov);
+ return;
+ case MP4PARSE_STATUS_MOOV_MISSING:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::no_moov);
+ return;
+ case MP4PARSE_STATUS_LSEL_NO_ESSENTIAL:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::lsel_no_essential);
+ return;
+ case MP4PARSE_STATUS_A1OP_NO_ESSENTIAL:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::a1op_no_essential);
+ return;
+ case MP4PARSE_STATUS_A1LX_ESSENTIAL:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::a1lx_essential);
+ return;
+ case MP4PARSE_STATUS_TXFORM_NO_ESSENTIAL:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::txform_no_essential);
+ return;
+ case MP4PARSE_STATUS_PITM_MISSING:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::no_primary_item);
+ return;
+ case MP4PARSE_STATUS_IMAGE_ITEM_TYPE:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::image_item_type);
+ return;
+ case MP4PARSE_STATUS_ITEM_TYPE_MISSING:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::item_type_missing);
+ return;
+ case MP4PARSE_STATUS_CONSTRUCTION_METHOD:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::construction_method);
+ return;
+ case MP4PARSE_STATUS_PITM_NOT_FOUND:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::item_loc_not_found);
+ return;
+ case MP4PARSE_STATUS_IDAT_MISSING:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::no_item_data_box);
+ return;
+ default:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::uncategorized);
+ return;
+ }
+
+ MOZ_LOG(sAVIFLog, LogLevel::Error,
+ ("[this=%p] unexpected Mp4parseStatus value: %d", this,
+ aResult.as<Mp4parseStatus>()));
+ MOZ_ASSERT(false, "unexpected Mp4parseStatus value");
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::invalid_parse_status);
+
+ } else if (aResult.is<NonDecoderResult>()) {
+ switch (aResult.as<NonDecoderResult>()) {
+ case NonDecoderResult::NeedMoreData:
+ return;
+ case NonDecoderResult::OutputAvailable:
+ return;
+ case NonDecoderResult::Complete:
+ return;
+ case NonDecoderResult::SizeOverflow:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::size_overflow);
+ return;
+ case NonDecoderResult::OutOfMemory:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::out_of_memory);
+ return;
+ case NonDecoderResult::PipeInitError:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::pipe_init_error);
+ return;
+ case NonDecoderResult::WriteBufferError:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::write_buffer_error);
+ return;
+ case NonDecoderResult::AlphaYSizeMismatch:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::alpha_y_sz_mismatch);
+ return;
+ case NonDecoderResult::AlphaYColorDepthMismatch:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::alpha_y_bpc_mismatch);
+ return;
+ case NonDecoderResult::MetadataImageSizeMismatch:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::ispe_mismatch);
+ return;
+ case NonDecoderResult::RenderSizeMismatch:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::render_size_mismatch);
+ return;
+ case NonDecoderResult::FrameSizeChanged:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::frame_size_changed);
+ return;
+ case NonDecoderResult::InvalidCICP:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::invalid_cicp);
+ return;
+ case NonDecoderResult::NoSamples:
+ AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::no_samples);
+ return;
+ }
+ MOZ_ASSERT_UNREACHABLE("unknown NonDecoderResult");
+ } else {
+ MOZ_ASSERT(aResult.is<Dav1dResult>() || aResult.is<AOMResult>());
+ AccumulateCategorical(aResult.is<Dav1dResult>() ? LABELS_AVIF_DECODER::dav1d
+ : LABELS_AVIF_DECODER::aom);
+ AccumulateCategorical(IsDecodeSuccess(aResult)
+ ? LABELS_AVIF_DECODE_RESULT::success
+ : LABELS_AVIF_DECODE_RESULT::decode_error);
+ }
+}
+
+Maybe<Telemetry::HistogramID> nsAVIFDecoder::SpeedHistogram() const {
+ return Some(Telemetry::IMAGE_DECODE_SPEED_AVIF);
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/decoders/nsAVIFDecoder.h b/image/decoders/nsAVIFDecoder.h
new file mode 100644
index 0000000000..59f6498202
--- /dev/null
+++ b/image/decoders/nsAVIFDecoder.h
@@ -0,0 +1,289 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_nsAVIFDecoder_h
+#define mozilla_image_decoders_nsAVIFDecoder_h
+
+#include "Decoder.h"
+#include "mozilla/gfx/Types.h"
+#include "MP4Metadata.h"
+#include "mp4parse.h"
+#include "SampleIterator.h"
+#include "SurfacePipe.h"
+
+#include "aom/aom_decoder.h"
+#include "dav1d/dav1d.h"
+
+#include "mozilla/Telemetry.h"
+
+namespace mozilla {
+namespace image {
+class RasterImage;
+class AVIFDecoderStream;
+class AVIFParser;
+class AVIFDecoderInterface;
+
+class nsAVIFDecoder final : public Decoder {
+ public:
+ virtual ~nsAVIFDecoder();
+
+ DecoderType GetType() const override { return DecoderType::AVIF; }
+
+ protected:
+ LexerResult DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) override;
+ Maybe<Telemetry::HistogramID> SpeedHistogram() const override;
+
+ private:
+ friend class DecoderFactory;
+ friend class AVIFDecoderInterface;
+ friend class AVIFParser;
+
+ // Decoders should only be instantiated via DecoderFactory.
+ explicit nsAVIFDecoder(RasterImage* aImage);
+
+ static intptr_t ReadSource(uint8_t* aDestBuf, uintptr_t aDestBufSize,
+ void* aUserData);
+
+ typedef int Dav1dResult;
+ enum class NonAOMCodecError { NoFrame, SizeOverflow };
+ typedef Variant<aom_codec_err_t, NonAOMCodecError> AOMResult;
+ enum class NonDecoderResult {
+ NeedMoreData,
+ OutputAvailable,
+ Complete,
+ SizeOverflow,
+ OutOfMemory,
+ PipeInitError,
+ WriteBufferError,
+ AlphaYSizeMismatch,
+ AlphaYColorDepthMismatch,
+ MetadataImageSizeMismatch,
+ RenderSizeMismatch,
+ FrameSizeChanged,
+ InvalidCICP,
+ NoSamples,
+ };
+ using DecodeResult =
+ Variant<Mp4parseStatus, NonDecoderResult, Dav1dResult, AOMResult>;
+ Mp4parseStatus CreateParser();
+ DecodeResult CreateDecoder();
+ DecodeResult DoDecodeInternal(SourceBufferIterator& aIterator,
+ IResumable* aOnResume);
+
+ static bool IsDecodeSuccess(const DecodeResult& aResult);
+
+ void RecordDecodeResultTelemetry(const DecodeResult& aResult);
+
+ Vector<uint8_t> mBufferedData;
+ RefPtr<AVIFDecoderStream> mBufferStream;
+
+ /// Pointer to the next place to read from mBufferedData
+ const uint8_t* mReadCursor = nullptr;
+
+ UniquePtr<AVIFParser> mParser = nullptr;
+ UniquePtr<AVIFDecoderInterface> mDecoder = nullptr;
+
+ bool mIsAnimated = false;
+ bool mHasAlpha = false;
+};
+
+class AVIFDecoderStream : public ByteStream {
+ public:
+ explicit AVIFDecoderStream(Vector<uint8_t>* aBuffer) { mBuffer = aBuffer; }
+
+ virtual bool ReadAt(int64_t offset, void* data, size_t size,
+ size_t* bytes_read) override;
+ virtual bool CachedReadAt(int64_t offset, void* data, size_t size,
+ size_t* bytes_read) override {
+ return ReadAt(offset, data, size, bytes_read);
+ };
+ virtual bool Length(int64_t* size) override;
+ virtual const uint8_t* GetContiguousAccess(int64_t aOffset,
+ size_t aSize) override;
+
+ private:
+ Vector<uint8_t>* mBuffer;
+};
+
+struct AVIFImage {
+ uint32_t mFrameNum = 0;
+ FrameTimeout mDuration = FrameTimeout::Zero();
+ RefPtr<MediaRawData> mColorImage = nullptr;
+ RefPtr<MediaRawData> mAlphaImage = nullptr;
+};
+
+class AVIFParser {
+ public:
+ static Mp4parseStatus Create(const Mp4parseIo* aIo, ByteStream* aBuffer,
+ UniquePtr<AVIFParser>& aParserOut,
+ bool aAllowSequences, bool aAnimateAVIFMajor);
+
+ ~AVIFParser();
+
+ const Mp4parseAvifInfo& GetInfo() const { return mInfo; }
+
+ nsAVIFDecoder::DecodeResult GetImage(AVIFImage& aImage);
+
+ bool IsAnimated() const;
+
+ private:
+ explicit AVIFParser(const Mp4parseIo* aIo);
+
+ Mp4parseStatus Init(ByteStream* aBuffer, bool aAllowSequences,
+ bool aAnimateAVIFMajor);
+
+ struct FreeAvifParser {
+ void operator()(Mp4parseAvifParser* aPtr) { mp4parse_avif_free(aPtr); }
+ };
+
+ const Mp4parseIo* mIo;
+ UniquePtr<Mp4parseAvifParser, FreeAvifParser> mParser = nullptr;
+ Mp4parseAvifInfo mInfo = {};
+
+ UniquePtr<SampleIterator> mColorSampleIter = nullptr;
+ UniquePtr<SampleIterator> mAlphaSampleIter = nullptr;
+ uint32_t mFrameNum = 0;
+};
+
+struct Dav1dPictureUnref {
+ void operator()(Dav1dPicture* aPtr) {
+ dav1d_picture_unref(aPtr);
+ delete aPtr;
+ }
+};
+
+using OwnedDav1dPicture = UniquePtr<Dav1dPicture, Dav1dPictureUnref>;
+
+class OwnedAOMImage {
+ public:
+ ~OwnedAOMImage();
+
+ static OwnedAOMImage* CopyFrom(aom_image_t* aImage, bool aIsAlpha);
+
+ aom_image_t* GetImage() { return mImage.isSome() ? mImage.ptr() : nullptr; }
+
+ private:
+ OwnedAOMImage();
+
+ bool CloneFrom(aom_image_t* aImage, bool aIsAlpha);
+
+ // The mImage's planes are referenced to mBuffer
+ Maybe<aom_image_t> mImage;
+ UniquePtr<uint8_t[]> mBuffer;
+};
+
+struct AVIFDecodedData : layers::PlanarYCbCrData {
+ public:
+ Maybe<OrientedIntSize> mRenderSize = Nothing();
+ gfx::CICP::ColourPrimaries mColourPrimaries = gfx::CICP::CP_UNSPECIFIED;
+ gfx::CICP::TransferCharacteristics mTransferCharacteristics =
+ gfx::CICP::TC_UNSPECIFIED;
+ gfx::CICP::MatrixCoefficients mMatrixCoefficients = gfx::CICP::MC_UNSPECIFIED;
+
+ OwnedDav1dPicture mColorDav1d;
+ OwnedDav1dPicture mAlphaDav1d;
+ UniquePtr<OwnedAOMImage> mColorAOM;
+ UniquePtr<OwnedAOMImage> mAlphaAOM;
+
+ // CICP values (either from the BMFF container or the AV1 sequence header) are
+ // used to create the colorspace transform. CICP::MatrixCoefficients is only
+ // stored for the sake of telemetry, since the relevant information for YUV ->
+ // RGB conversion is stored in mYUVColorSpace.
+ //
+ // There are three potential sources of color information for an AVIF:
+ // 1. ICC profile via a ColourInformationBox (colr) defined in [ISOBMFF]
+ // § 12.1.5 "Colour information" and [MIAF] § 7.3.6.4 "Colour information
+ // property"
+ // 2. NCLX (AKA CICP see [ITU-T H.273]) values in the same
+ // ColourInformationBox
+ // which can have an ICC profile or NCLX values, not both).
+ // 3. NCLX values in the AV1 bitstream
+ //
+ // The 'colr' box is optional, but there are always CICP values in the AV1
+ // bitstream, so it is possible to have both. Per ISOBMFF § 12.1.5.1
+ // > If colour information is supplied in both this box, and also in the
+ // > video bitstream, this box takes precedence, and over-rides the
+ // > information in the bitstream.
+ //
+ // If present, the ICC profile takes precedence over CICP values, but only
+ // specifies the color space, not the matrix coefficients necessary to convert
+ // YCbCr data (as most AVIF are encoded) to RGB. The matrix coefficients are
+ // always derived from the CICP values for matrix_coefficients (and
+ // potentially colour_primaries, but in that case only the CICP values for
+ // colour_primaries will be used, not anything harvested from the ICC
+ // profile).
+ //
+ // If there is no ICC profile, the color space transform will be based on the
+ // CICP values either from the 'colr' box, or if absent/unspecified, the
+ // decoded AV1 sequence header.
+ //
+ // For values that are 2 (meaning unspecified) after trying both, the
+ // fallback values are:
+ // - CP: 1 (BT.709/sRGB)
+ // - TC: 13 (sRGB)
+ // - MC: 6 (BT.601)
+ // - Range: Full
+ //
+ // Additional details here:
+ // <https://github.com/AOMediaCodec/libavif/wiki/CICP#unspecified>. Note
+ // that this contradicts the current version of [MIAF] § 7.3.6.4 which
+ // specifies MC=1 (BT.709). This is revised in [MIAF DAMD2] and confirmed by
+ // <https://github.com/AOMediaCodec/av1-avif/issues/77#issuecomment-676526097>
+ //
+ // The precedence for applying the various values and defaults in the event
+ // no valid values are found are managed by the following functions.
+ //
+ // References:
+ // [ISOBMFF]: ISO/IEC 14496-12:2020 <https://www.iso.org/standard/74428.html>
+ // [MIAF]: ISO/IEC 23000-22:2019 <https://www.iso.org/standard/74417.html>
+ // [MIAF DAMD2]: ISO/IEC 23000-22:2019/FDAmd 2
+ // <https://www.iso.org/standard/81634.html>
+ // [ITU-T H.273]: Rec. ITU-T H.273 (12/2016)
+ // <https://www.itu.int/rec/T-REC-H.273-201612-I/en>
+ void SetCicpValues(
+ const Mp4parseNclxColourInformation* aNclx,
+ const gfx::CICP::ColourPrimaries aAv1ColourPrimaries,
+ const gfx::CICP::TransferCharacteristics aAv1TransferCharacteristics,
+ const gfx::CICP::MatrixCoefficients aAv1MatrixCoefficients);
+};
+
+// An interface to do decode and get the decoded data
+class AVIFDecoderInterface {
+ public:
+ using Dav1dResult = nsAVIFDecoder::Dav1dResult;
+ using NonAOMCodecError = nsAVIFDecoder::NonAOMCodecError;
+ using AOMResult = nsAVIFDecoder::AOMResult;
+ using NonDecoderResult = nsAVIFDecoder::NonDecoderResult;
+ using DecodeResult = nsAVIFDecoder::DecodeResult;
+
+ virtual ~AVIFDecoderInterface() = default;
+
+ // Set the mDecodedData if Decode() succeeds
+ virtual DecodeResult Decode(bool aShouldSendTelemetry,
+ const Mp4parseAvifInfo& aAVIFInfo,
+ const AVIFImage& aSamples) = 0;
+ // Must be called only once after Decode() succeeds
+ UniquePtr<AVIFDecodedData> GetDecodedData() {
+ MOZ_ASSERT(mDecodedData);
+ return std::move(mDecodedData);
+ }
+
+ protected:
+ explicit AVIFDecoderInterface() = default;
+
+ inline static bool IsDecodeSuccess(const DecodeResult& aResult) {
+ return nsAVIFDecoder::IsDecodeSuccess(aResult);
+ }
+
+ // The mDecodedData is valid after Decode() succeeds
+ UniquePtr<AVIFDecodedData> mDecodedData;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_decoders_nsAVIFDecoder_h
diff --git a/image/decoders/nsBMPDecoder.cpp b/image/decoders/nsBMPDecoder.cpp
new file mode 100644
index 0000000000..da971e054f
--- /dev/null
+++ b/image/decoders/nsBMPDecoder.cpp
@@ -0,0 +1,1275 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// This is a cross-platform BMP Decoder, which should work everywhere,
+// including big-endian machines like the PowerPC.
+//
+// BMP is a format that has been extended multiple times. To understand the
+// decoder you need to understand this history. The summary of the history
+// below was determined from the following documents.
+//
+// - http://www.fileformat.info/format/bmp/egff.htm
+// - http://www.fileformat.info/format/os2bmp/egff.htm
+// - http://fileformats.archiveteam.org/wiki/BMP
+// - http://fileformats.archiveteam.org/wiki/OS/2_BMP
+// - https://en.wikipedia.org/wiki/BMP_file_format
+// - https://upload.wikimedia.org/wikipedia/commons/c/c4/BMPfileFormat.png
+//
+// WINDOWS VERSIONS OF THE BMP FORMAT
+// ----------------------------------
+// WinBMPv1.
+// - This version is no longer used and can be ignored.
+//
+// WinBMPv2.
+// - First is a 14 byte file header that includes: the magic number ("BM"),
+// file size, and offset to the pixel data (|mDataOffset|).
+// - Next is a 12 byte info header which includes: the info header size
+// (mBIHSize), width, height, number of color planes, and bits-per-pixel
+// (|mBpp|) which must be 1, 4, 8 or 24.
+// - Next is the semi-optional color table, which has length 2^|mBpp| and has 3
+// bytes per value (BGR). The color table is required if |mBpp| is 1, 4, or 8.
+// - Next is an optional gap.
+// - Next is the pixel data, which is pointed to by |mDataOffset|.
+//
+// WinBMPv3. This is the most widely used version.
+// - It changed the info header to 40 bytes by taking the WinBMPv2 info
+// header, enlargening its width and height fields, and adding more fields
+// including: a compression type (|mCompression|) and number of colors
+// (|mNumColors|).
+// - The semi-optional color table is now 4 bytes per value (BGR0), and its
+// length is |mNumColors|, or 2^|mBpp| if |mNumColors| is zero.
+// - |mCompression| can be RGB (i.e. no compression), RLE4 (if |mBpp|==4) or
+// RLE8 (if |mBpp|==8) values.
+//
+// WinBMPv3-NT. A variant of WinBMPv3.
+// - It did not change the info header layout from WinBMPv3.
+// - |mBpp| can now be 16 or 32, in which case |mCompression| can be RGB or the
+// new BITFIELDS value; in the latter case an additional 12 bytes of color
+// bitfields follow the info header.
+//
+// WinBMPv4.
+// - It extended the info header to 108 bytes, including the 12 bytes of color
+// mask data from WinBMPv3-NT, plus alpha mask data, and also color-space and
+// gamma correction fields.
+//
+// WinBMPv5.
+// - It extended the info header to 124 bytes, adding color profile data.
+// - It also added an optional color profile table after the pixel data (and
+// another optional gap).
+//
+// WinBMPv3-ICO. This is a variant of WinBMPv3.
+// - It's the BMP format used for BMP images within ICO files.
+// - The only difference with WinBMPv3 is that if an image is 32bpp and has no
+// compression, then instead of treating the pixel data as 0RGB it is treated
+// as ARGB, but only if one or more of the A values are non-zero.
+//
+// Clipboard variants.
+// - It's the BMP format used for BMP images captured from the clipboard.
+// - It is missing the file header, containing the BM signature and the data
+// offset. Instead the data begins after the header.
+// - If it uses BITFIELDS compression, then there is always an additional 12
+// bytes of data after the header that must be read. In WinBMPv4+, the masks
+// are supposed to be included in the header size, which are the values we use
+// for decoding purposes, but there is additional three masks following the
+// header which must be skipped to get to the pixel data.
+//
+// OS/2 VERSIONS OF THE BMP FORMAT
+// -------------------------------
+// OS2-BMPv1.
+// - Almost identical to WinBMPv2; the differences are basically ignorable.
+//
+// OS2-BMPv2.
+// - Similar to WinBMPv3.
+// - The info header is 64 bytes but can be reduced to as little as 16; any
+// omitted fields are treated as zero. The first 40 bytes of these fields are
+// nearly identical to the WinBMPv3 info header; the remaining 24 bytes are
+// different.
+// - Also adds compression types "Huffman 1D" and "RLE24", which we don't
+// support.
+// - We treat OS2-BMPv2 files as if they are WinBMPv3 (i.e. ignore the extra 24
+// bytes in the info header), which in practice is good enough.
+
+#include "ImageLogging.h"
+#include "nsBMPDecoder.h"
+
+#include <stdlib.h>
+
+#include "mozilla/Attributes.h"
+#include "mozilla/EndianUtils.h"
+#include "mozilla/Likely.h"
+#include "mozilla/UniquePtrExtensions.h"
+
+#include "RasterImage.h"
+#include "SurfacePipeFactory.h"
+#include "gfxPlatform.h"
+#include <algorithm>
+
+using namespace mozilla::gfx;
+
+namespace mozilla {
+namespace image {
+namespace bmp {
+
+struct Compression {
+ enum { RGB = 0, RLE8 = 1, RLE4 = 2, BITFIELDS = 3 };
+};
+
+// RLE escape codes and constants.
+struct RLE {
+ enum {
+ ESCAPE = 0,
+ ESCAPE_EOL = 0,
+ ESCAPE_EOF = 1,
+ ESCAPE_DELTA = 2,
+
+ SEGMENT_LENGTH = 2,
+ DELTA_LENGTH = 2
+ };
+};
+
+} // namespace bmp
+
+using namespace bmp;
+
+static double FixedPoint2Dot30_To_Double(uint32_t aFixed) {
+ constexpr double factor = 1.0 / 1073741824.0; // 2^-30
+ return double(aFixed) * factor;
+}
+
+static float FixedPoint16Dot16_To_Float(uint32_t aFixed) {
+ constexpr double factor = 1.0 / 65536.0; // 2^-16
+ return double(aFixed) * factor;
+}
+
+static float CalRbgEndpointToQcms(const CalRgbEndpoint& aIn,
+ qcms_CIE_xyY& aOut) {
+ aOut.x = FixedPoint2Dot30_To_Double(aIn.mX);
+ aOut.y = FixedPoint2Dot30_To_Double(aIn.mY);
+ aOut.Y = FixedPoint2Dot30_To_Double(aIn.mZ);
+ return FixedPoint16Dot16_To_Float(aIn.mGamma);
+}
+
+static void ReadCalRgbEndpoint(const char* aData, uint32_t aEndpointOffset,
+ uint32_t aGammaOffset, CalRgbEndpoint& aOut) {
+ aOut.mX = LittleEndian::readUint32(aData + aEndpointOffset);
+ aOut.mY = LittleEndian::readUint32(aData + aEndpointOffset + 4);
+ aOut.mZ = LittleEndian::readUint32(aData + aEndpointOffset + 8);
+ aOut.mGamma = LittleEndian::readUint32(aData + aGammaOffset);
+}
+
+/// Sets the pixel data in aDecoded to the given values.
+/// @param aDecoded pointer to pixel to be set, will be incremented to point to
+/// the next pixel.
+static void SetPixel(uint32_t*& aDecoded, uint8_t aRed, uint8_t aGreen,
+ uint8_t aBlue, uint8_t aAlpha = 0xFF) {
+ *aDecoded++ = gfxPackedPixelNoPreMultiply(aAlpha, aRed, aGreen, aBlue);
+}
+
+static void SetPixel(uint32_t*& aDecoded, uint8_t idx,
+ const UniquePtr<ColorTableEntry[]>& aColors) {
+ SetPixel(aDecoded, aColors[idx].mRed, aColors[idx].mGreen,
+ aColors[idx].mBlue);
+}
+
+/// Sets two (or one if aCount = 1) pixels
+/// @param aDecoded where the data is stored. Will be moved 4 resp 8 bytes
+/// depending on whether one or two pixels are written.
+/// @param aData The values for the two pixels
+/// @param aCount Current count. Is decremented by one or two.
+static void Set4BitPixel(uint32_t*& aDecoded, uint8_t aData, uint32_t& aCount,
+ const UniquePtr<ColorTableEntry[]>& aColors) {
+ uint8_t idx = aData >> 4;
+ SetPixel(aDecoded, idx, aColors);
+ if (--aCount > 0) {
+ idx = aData & 0xF;
+ SetPixel(aDecoded, idx, aColors);
+ --aCount;
+ }
+}
+
+static mozilla::LazyLogModule sBMPLog("BMPDecoder");
+
+// The length of the mBIHSize field in the info header.
+static const uint32_t BIHSIZE_FIELD_LENGTH = 4;
+
+nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength,
+ bool aForClipboard)
+ : Decoder(aImage),
+ mLexer(Transition::To(aState, aLength), Transition::TerminateSuccess()),
+ mIsWithinICO(false),
+ mIsForClipboard(aForClipboard),
+ mMayHaveTransparency(false),
+ mDoesHaveTransparency(false),
+ mNumColors(0),
+ mColors(nullptr),
+ mBytesPerColor(0),
+ mPreGapLength(0),
+ mPixelRowSize(0),
+ mCurrentRow(0),
+ mCurrentPos(0),
+ mAbsoluteModeNumPixels(0) {}
+
+// Constructor for normal BMP files or from the clipboard.
+nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, bool aForClipboard)
+ : nsBMPDecoder(aImage,
+ aForClipboard ? State::INFO_HEADER_SIZE : State::FILE_HEADER,
+ aForClipboard ? BIHSIZE_FIELD_LENGTH : FILE_HEADER_LENGTH,
+ aForClipboard) {}
+
+// Constructor used for WinBMPv3-ICO files, which lack a file header.
+nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, uint32_t aDataOffset)
+ : nsBMPDecoder(aImage, State::INFO_HEADER_SIZE, BIHSIZE_FIELD_LENGTH,
+ /* aForClipboard */ false) {
+ SetIsWithinICO();
+
+ // Even though the file header isn't present in this case, the dataOffset
+ // field is set as if it is, and so we must increment mPreGapLength
+ // accordingly.
+ mPreGapLength += FILE_HEADER_LENGTH;
+
+ // This is the one piece of data we normally get from a BMP file header, so
+ // it must be provided via an argument.
+ mH.mDataOffset = aDataOffset;
+}
+
+nsBMPDecoder::~nsBMPDecoder() {}
+
+// Obtains the size of the compressed image resource.
+int32_t nsBMPDecoder::GetCompressedImageSize() const {
+ // In the RGB case mImageSize might not be set, so compute it manually.
+ MOZ_ASSERT(mPixelRowSize != 0);
+ return mH.mCompression == Compression::RGB ? mPixelRowSize * AbsoluteHeight()
+ : mH.mImageSize;
+}
+
+nsresult nsBMPDecoder::BeforeFinishInternal() {
+ if (!IsMetadataDecode() && !mImageData) {
+ return NS_ERROR_FAILURE; // No image; something went wrong.
+ }
+
+ return NS_OK;
+}
+
+nsresult nsBMPDecoder::FinishInternal() {
+ // We shouldn't be called in error cases.
+ MOZ_ASSERT(!HasError(), "Can't call FinishInternal on error!");
+
+ // We should never make multiple frames.
+ MOZ_ASSERT(GetFrameCount() <= 1, "Multiple BMP frames?");
+
+ // Send notifications if appropriate.
+ if (!IsMetadataDecode() && HasSize()) {
+ // We should have image data.
+ MOZ_ASSERT(mImageData);
+
+ // If it was truncated, fill in the missing pixels as black.
+ while (mCurrentRow > 0) {
+ uint32_t* dst = RowBuffer();
+ while (mCurrentPos < mH.mWidth) {
+ SetPixel(dst, 0, 0, 0);
+ mCurrentPos++;
+ }
+ mCurrentPos = 0;
+ FinishRow();
+ }
+
+ MOZ_ASSERT_IF(mDoesHaveTransparency, mMayHaveTransparency);
+
+ // We have transparency if we either detected some in the image itself
+ // (i.e., |mDoesHaveTransparency| is true) or we're in an ICO, which could
+ // mean we have an AND mask that provides transparency (i.e., |mIsWithinICO|
+ // is true).
+ // XXX(seth): We can tell when we create the decoder if the AND mask is
+ // present, so we could be more precise about this.
+ const Opacity opacity = mDoesHaveTransparency || mIsWithinICO
+ ? Opacity::SOME_TRANSPARENCY
+ : Opacity::FULLY_OPAQUE;
+
+ PostFrameStop(opacity);
+ PostDecodeDone();
+ }
+
+ return NS_OK;
+}
+
+// ----------------------------------------
+// Actual Data Processing
+// ----------------------------------------
+
+void BitFields::Value::Set(uint32_t aMask) {
+ mMask = aMask;
+
+ // Handle this exceptional case first. The chosen values don't matter
+ // (because a mask of zero will always give a value of zero) except that
+ // mBitWidth:
+ // - shouldn't be zero, because that would cause an infinite loop in Get();
+ // - shouldn't be 5 or 8, because that could cause a false positive match in
+ // IsR5G5B5() or IsR8G8B8().
+ if (mMask == 0x0) {
+ mRightShift = 0;
+ mBitWidth = 1;
+ return;
+ }
+
+ // Find the rightmost 1.
+ uint8_t i;
+ for (i = 0; i < 32; i++) {
+ if (mMask & (1 << i)) {
+ break;
+ }
+ }
+ mRightShift = i;
+
+ // Now find the leftmost 1 in the same run of 1s. (If there are multiple runs
+ // of 1s -- which isn't valid -- we'll behave as if only the lowest run was
+ // present, which seems reasonable.)
+ for (i = i + 1; i < 32; i++) {
+ if (!(mMask & (1 << i))) {
+ break;
+ }
+ }
+ mBitWidth = i - mRightShift;
+}
+
+MOZ_ALWAYS_INLINE uint8_t BitFields::Value::Get(uint32_t aValue) const {
+ // Extract the unscaled value.
+ uint32_t v = (aValue & mMask) >> mRightShift;
+
+ // Idea: to upscale v precisely we need to duplicate its bits, possibly
+ // repeatedly, possibly partially in the last case, from bit 7 down to bit 0
+ // in v2. For example:
+ //
+ // - mBitWidth=1: v2 = v<<7 | v<<6 | ... | v<<1 | v>>0 k -> kkkkkkkk
+ // - mBitWidth=2: v2 = v<<6 | v<<4 | v<<2 | v>>0 jk -> jkjkjkjk
+ // - mBitWidth=3: v2 = v<<5 | v<<2 | v>>1 ijk -> ijkijkij
+ // - mBitWidth=4: v2 = v<<4 | v>>0 hijk -> hijkhijk
+ // - mBitWidth=5: v2 = v<<3 | v>>2 ghijk -> ghijkghi
+ // - mBitWidth=6: v2 = v<<2 | v>>4 fghijk -> fghijkfg
+ // - mBitWidth=7: v2 = v<<1 | v>>6 efghijk -> efghijke
+ // - mBitWidth=8: v2 = v>>0 defghijk -> defghijk
+ // - mBitWidth=9: v2 = v>>1 cdefghijk -> cdefghij
+ // - mBitWidth=10: v2 = v>>2 bcdefghijk -> bcdefghi
+ // - mBitWidth=11: v2 = v>>3 abcdefghijk -> abcdefgh
+ // - etc.
+ //
+ uint8_t v2 = 0;
+ int32_t i; // must be a signed integer
+ for (i = 8 - mBitWidth; i > 0; i -= mBitWidth) {
+ v2 |= v << uint32_t(i);
+ }
+ v2 |= v >> uint32_t(-i);
+ return v2;
+}
+
+MOZ_ALWAYS_INLINE uint8_t BitFields::Value::GetAlpha(uint32_t aValue,
+ bool& aHasAlphaOut) const {
+ if (mMask == 0x0) {
+ return 0xff;
+ }
+ aHasAlphaOut = true;
+ return Get(aValue);
+}
+
+MOZ_ALWAYS_INLINE uint8_t BitFields::Value::Get5(uint32_t aValue) const {
+ MOZ_ASSERT(mBitWidth == 5);
+ uint32_t v = (aValue & mMask) >> mRightShift;
+ return (v << 3u) | (v >> 2u);
+}
+
+MOZ_ALWAYS_INLINE uint8_t BitFields::Value::Get8(uint32_t aValue) const {
+ MOZ_ASSERT(mBitWidth == 8);
+ uint32_t v = (aValue & mMask) >> mRightShift;
+ return v;
+}
+
+void BitFields::SetR5G5B5() {
+ mRed.Set(0x7c00);
+ mGreen.Set(0x03e0);
+ mBlue.Set(0x001f);
+}
+
+void BitFields::SetR8G8B8() {
+ mRed.Set(0xff0000);
+ mGreen.Set(0xff00);
+ mBlue.Set(0x00ff);
+}
+
+bool BitFields::IsR5G5B5() const {
+ return mRed.mBitWidth == 5 && mGreen.mBitWidth == 5 && mBlue.mBitWidth == 5 &&
+ mAlpha.mMask == 0x0;
+}
+
+bool BitFields::IsR8G8B8() const {
+ return mRed.mBitWidth == 8 && mGreen.mBitWidth == 8 && mBlue.mBitWidth == 8 &&
+ mAlpha.mMask == 0x0;
+}
+
+uint32_t* nsBMPDecoder::RowBuffer() { return mRowBuffer.get() + mCurrentPos; }
+
+void nsBMPDecoder::ClearRowBufferRemainder() {
+ int32_t len = mH.mWidth - mCurrentPos;
+ memset(RowBuffer(), mMayHaveTransparency ? 0 : 0xFF, len * sizeof(uint32_t));
+}
+
+void nsBMPDecoder::FinishRow() {
+ mPipe.WriteBuffer(mRowBuffer.get());
+ Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect();
+ if (invalidRect) {
+ PostInvalidation(invalidRect->mInputSpaceRect,
+ Some(invalidRect->mOutputSpaceRect));
+ }
+ mCurrentRow--;
+}
+
+LexerResult nsBMPDecoder::DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) {
+ MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
+
+ return mLexer.Lex(
+ aIterator, aOnResume,
+ [=](State aState, const char* aData, size_t aLength) {
+ switch (aState) {
+ case State::FILE_HEADER:
+ return ReadFileHeader(aData, aLength);
+ case State::INFO_HEADER_SIZE:
+ return ReadInfoHeaderSize(aData, aLength);
+ case State::INFO_HEADER_REST:
+ return ReadInfoHeaderRest(aData, aLength);
+ case State::BITFIELDS:
+ return ReadBitfields(aData, aLength);
+ case State::SKIP_TO_COLOR_PROFILE:
+ return Transition::ContinueUnbuffered(State::SKIP_TO_COLOR_PROFILE);
+ case State::FOUND_COLOR_PROFILE:
+ return Transition::To(State::COLOR_PROFILE,
+ mH.mColorSpace.mProfile.mLength);
+ case State::COLOR_PROFILE:
+ return ReadColorProfile(aData, aLength);
+ case State::ALLOCATE_SURFACE:
+ return AllocateSurface();
+ case State::COLOR_TABLE:
+ return ReadColorTable(aData, aLength);
+ case State::GAP:
+ return SkipGap();
+ case State::AFTER_GAP:
+ return AfterGap();
+ case State::PIXEL_ROW:
+ return ReadPixelRow(aData);
+ case State::RLE_SEGMENT:
+ return ReadRLESegment(aData);
+ case State::RLE_DELTA:
+ return ReadRLEDelta(aData);
+ case State::RLE_ABSOLUTE:
+ return ReadRLEAbsolute(aData, aLength);
+ default:
+ MOZ_CRASH("Unknown State");
+ }
+ });
+}
+
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadFileHeader(
+ const char* aData, size_t aLength) {
+ mPreGapLength += aLength;
+
+ bool signatureOk = aData[0] == 'B' && aData[1] == 'M';
+ if (!signatureOk) {
+ return Transition::TerminateFailure();
+ }
+
+ // We ignore the filesize (aData + 2) and reserved (aData + 6) fields.
+
+ mH.mDataOffset = LittleEndian::readUint32(aData + 10);
+
+ return Transition::To(State::INFO_HEADER_SIZE, BIHSIZE_FIELD_LENGTH);
+}
+
+// We read the info header in two steps: (a) read the mBIHSize field to
+// determine how long the header is; (b) read the rest of the header.
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadInfoHeaderSize(
+ const char* aData, size_t aLength) {
+ mH.mBIHSize = LittleEndian::readUint32(aData);
+
+ // Data offset can be wrong so fix it using the BIH size.
+ if (!mIsForClipboard && mH.mDataOffset < mPreGapLength + mH.mBIHSize) {
+ mH.mDataOffset = mPreGapLength + mH.mBIHSize;
+ }
+
+ mPreGapLength += aLength;
+
+ bool bihSizeOk = mH.mBIHSize == InfoHeaderLength::WIN_V2 ||
+ mH.mBIHSize == InfoHeaderLength::WIN_V3 ||
+ mH.mBIHSize == InfoHeaderLength::WIN_V4 ||
+ mH.mBIHSize == InfoHeaderLength::WIN_V5 ||
+ (mH.mBIHSize >= InfoHeaderLength::OS2_V2_MIN &&
+ mH.mBIHSize <= InfoHeaderLength::OS2_V2_MAX);
+ if (!bihSizeOk) {
+ return Transition::TerminateFailure();
+ }
+ // ICO BMPs must have a WinBMPv3 header. nsICODecoder should have already
+ // terminated decoding if this isn't the case.
+ MOZ_ASSERT_IF(mIsWithinICO, mH.mBIHSize == InfoHeaderLength::WIN_V3);
+
+ return Transition::To(State::INFO_HEADER_REST,
+ mH.mBIHSize - BIHSIZE_FIELD_LENGTH);
+}
+
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadInfoHeaderRest(
+ const char* aData, size_t aLength) {
+ mPreGapLength += aLength;
+
+ // |mWidth| and |mHeight| may be signed (Windows) or unsigned (OS/2). We just
+ // read as unsigned because in practice that's good enough.
+ if (mH.mBIHSize == InfoHeaderLength::WIN_V2) {
+ mH.mWidth = LittleEndian::readUint16(aData + 0);
+ mH.mHeight = LittleEndian::readUint16(aData + 2);
+ // We ignore the planes (aData + 4) field; it should always be 1.
+ mH.mBpp = LittleEndian::readUint16(aData + 6);
+ } else {
+ mH.mWidth = LittleEndian::readUint32(aData + 0);
+ mH.mHeight = LittleEndian::readUint32(aData + 4);
+ // We ignore the planes (aData + 4) field; it should always be 1.
+ mH.mBpp = LittleEndian::readUint16(aData + 10);
+
+ // For OS2-BMPv2 the info header may be as little as 16 bytes, so be
+ // careful for these fields.
+ mH.mCompression = aLength >= 16 ? LittleEndian::readUint32(aData + 12) : 0;
+ mH.mImageSize = aLength >= 20 ? LittleEndian::readUint32(aData + 16) : 0;
+ // We ignore the xppm (aData + 20) and yppm (aData + 24) fields.
+ mH.mNumColors = aLength >= 32 ? LittleEndian::readUint32(aData + 28) : 0;
+ // We ignore the important_colors (aData + 36) field.
+
+ // Read color management properties we may need later.
+ mH.mCsType =
+ aLength >= 56
+ ? static_cast<InfoColorSpace>(LittleEndian::readUint32(aData + 52))
+ : InfoColorSpace::SRGB;
+ mH.mCsIntent = aLength >= 108 ? static_cast<InfoColorIntent>(
+ LittleEndian::readUint32(aData + 104))
+ : InfoColorIntent::IMAGES;
+
+ switch (mH.mCsType) {
+ case InfoColorSpace::CALIBRATED_RGB:
+ if (aLength >= 104) {
+ ReadCalRgbEndpoint(aData, 56, 92, mH.mColorSpace.mCalibrated.mRed);
+ ReadCalRgbEndpoint(aData, 68, 96, mH.mColorSpace.mCalibrated.mGreen);
+ ReadCalRgbEndpoint(aData, 80, 100, mH.mColorSpace.mCalibrated.mBlue);
+ } else {
+ mH.mCsType = InfoColorSpace::SRGB;
+ }
+ break;
+ case InfoColorSpace::EMBEDDED:
+ if (aLength >= 116) {
+ mH.mColorSpace.mProfile.mOffset =
+ LittleEndian::readUint32(aData + 108);
+ mH.mColorSpace.mProfile.mLength =
+ LittleEndian::readUint32(aData + 112);
+ } else {
+ mH.mCsType = InfoColorSpace::SRGB;
+ }
+ break;
+ case InfoColorSpace::LINKED:
+ case InfoColorSpace::SRGB:
+ case InfoColorSpace::WIN:
+ default:
+ // Nothing to be done at this time.
+ break;
+ }
+
+ // For WinBMPv4, WinBMPv5 and (possibly) OS2-BMPv2 there are additional
+ // fields in the info header which we ignore, with the possible exception
+ // of the color bitfields (see below).
+ }
+
+ // The height for BMPs embedded inside an ICO includes spaces for the AND
+ // mask even if it is not present, thus we need to adjust for that here.
+ if (mIsWithinICO) {
+ // XXX(seth): Should we really be writing the absolute value from
+ // the BIH below? Seems like this could be problematic for inverted BMPs.
+ mH.mHeight = abs(mH.mHeight) / 2;
+ }
+
+ // Run with MOZ_LOG=BMPDecoder:5 set to see this output.
+ MOZ_LOG(sBMPLog, LogLevel::Debug,
+ ("BMP: bihsize=%u, %d x %d, bpp=%u, compression=%u, colors=%u, "
+ "data-offset=%u\n",
+ mH.mBIHSize, mH.mWidth, mH.mHeight, uint32_t(mH.mBpp),
+ mH.mCompression, mH.mNumColors, mH.mDataOffset));
+
+ // BMPs with negative width are invalid. Also, reject extremely wide images
+ // to keep the math sane. And reject INT_MIN as a height because you can't
+ // get its absolute value (because -INT_MIN is one more than INT_MAX).
+ const int32_t k64KWidth = 0x0000FFFF;
+ bool sizeOk =
+ 0 <= mH.mWidth && mH.mWidth <= k64KWidth && mH.mHeight != INT_MIN;
+ if (!sizeOk) {
+ return Transition::TerminateFailure();
+ }
+
+ // Check mBpp and mCompression.
+ bool bppCompressionOk =
+ (mH.mCompression == Compression::RGB &&
+ (mH.mBpp == 1 || mH.mBpp == 4 || mH.mBpp == 8 || mH.mBpp == 16 ||
+ mH.mBpp == 24 || mH.mBpp == 32)) ||
+ (mH.mCompression == Compression::RLE8 && mH.mBpp == 8) ||
+ (mH.mCompression == Compression::RLE4 && mH.mBpp == 4) ||
+ (mH.mCompression == Compression::BITFIELDS &&
+ // For BITFIELDS compression we require an exact match for one of the
+ // WinBMP BIH sizes; this clearly isn't an OS2 BMP.
+ (mH.mBIHSize == InfoHeaderLength::WIN_V3 ||
+ mH.mBIHSize == InfoHeaderLength::WIN_V4 ||
+ mH.mBIHSize == InfoHeaderLength::WIN_V5) &&
+ (mH.mBpp == 16 || mH.mBpp == 32));
+ if (!bppCompressionOk) {
+ return Transition::TerminateFailure();
+ }
+
+ // Initialize our current row to the top of the image.
+ mCurrentRow = AbsoluteHeight();
+
+ // Round it up to the nearest byte count, then pad to 4-byte boundary.
+ // Compute this even for a metadate decode because GetCompressedImageSize()
+ // relies on it.
+ mPixelRowSize = (mH.mBpp * mH.mWidth + 7) / 8;
+ uint32_t surplus = mPixelRowSize % 4;
+ if (surplus != 0) {
+ mPixelRowSize += 4 - surplus;
+ }
+
+ size_t bitFieldsLengthStillToRead = 0;
+ if (mH.mCompression == Compression::BITFIELDS) {
+ // Need to read bitfields.
+ if (mH.mBIHSize >= InfoHeaderLength::WIN_V4) {
+ // Bitfields are present in the info header, so we can read them
+ // immediately.
+ mBitFields.ReadFromHeader(aData + 36, /* aReadAlpha = */ true);
+
+ // If this came from the clipboard, then we know that even if the header
+ // explicitly includes the bitfield masks, we need to add an additional
+ // offset for the start of the RGB data.
+ if (mIsForClipboard) {
+ mH.mDataOffset += BitFields::LENGTH;
+ }
+ } else {
+ // Bitfields are present after the info header, so we will read them in
+ // ReadBitfields().
+ bitFieldsLengthStillToRead = BitFields::LENGTH;
+ }
+ } else if (mH.mBpp == 16) {
+ // No bitfields specified; use the default 5-5-5 values.
+ mBitFields.SetR5G5B5();
+ } else if (mH.mBpp == 32) {
+ // No bitfields specified; use the default 8-8-8 values.
+ mBitFields.SetR8G8B8();
+ }
+
+ return Transition::To(State::BITFIELDS, bitFieldsLengthStillToRead);
+}
+
+void BitFields::ReadFromHeader(const char* aData, bool aReadAlpha) {
+ mRed.Set(LittleEndian::readUint32(aData + 0));
+ mGreen.Set(LittleEndian::readUint32(aData + 4));
+ mBlue.Set(LittleEndian::readUint32(aData + 8));
+ if (aReadAlpha) {
+ mAlpha.Set(LittleEndian::readUint32(aData + 12));
+ }
+}
+
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadBitfields(
+ const char* aData, size_t aLength) {
+ mPreGapLength += aLength;
+
+ // If aLength is zero there are no bitfields to read, or we already read them
+ // in ReadInfoHeader().
+ if (aLength != 0) {
+ mBitFields.ReadFromHeader(aData, /* aReadAlpha = */ false);
+ }
+
+ // Note that RLE-encoded BMPs might be transparent because the 'delta' mode
+ // can skip pixels and cause implicit transparency.
+ mMayHaveTransparency = mIsWithinICO || mH.mCompression == Compression::RLE8 ||
+ mH.mCompression == Compression::RLE4 ||
+ (mH.mCompression == Compression::BITFIELDS &&
+ mBitFields.mAlpha.IsPresent());
+ if (mMayHaveTransparency) {
+ PostHasTransparency();
+ }
+
+ // Post our size to the superclass.
+ PostSize(mH.mWidth, AbsoluteHeight());
+ if (HasError()) {
+ return Transition::TerminateFailure();
+ }
+
+ // We've now read all the headers. If we're doing a metadata decode, we're
+ // done.
+ if (IsMetadataDecode()) {
+ return Transition::TerminateSuccess();
+ }
+
+ // Set up the color table, if present; it'll be filled in by ReadColorTable().
+ if (mH.mBpp <= 8) {
+ mNumColors = 1 << mH.mBpp;
+ if (0 < mH.mNumColors && mH.mNumColors < mNumColors) {
+ mNumColors = mH.mNumColors;
+ }
+
+ // Always allocate and zero 256 entries, even though mNumColors might be
+ // smaller, because the file might erroneously index past mNumColors.
+ mColors = MakeUniqueFallible<ColorTableEntry[]>(256);
+ if (NS_WARN_IF(!mColors)) {
+ return Transition::TerminateFailure();
+ }
+ memset(mColors.get(), 0, 256 * sizeof(ColorTableEntry));
+
+ // OS/2 Bitmaps have no padding byte.
+ mBytesPerColor = (mH.mBIHSize == InfoHeaderLength::WIN_V2) ? 3 : 4;
+ }
+
+ if (mCMSMode != CMSMode::Off) {
+ switch (mH.mCsType) {
+ case InfoColorSpace::EMBEDDED:
+ return SeekColorProfile(aLength);
+ case InfoColorSpace::CALIBRATED_RGB:
+ PrepareCalibratedColorProfile();
+ break;
+ case InfoColorSpace::SRGB:
+ case InfoColorSpace::WIN:
+ MOZ_LOG(sBMPLog, LogLevel::Debug, ("using sRGB color profile\n"));
+ if (mColors) {
+ // We will transform the color table instead of the output pixels.
+ mTransform = GetCMSsRGBTransform(SurfaceFormat::R8G8B8);
+ } else {
+ mTransform = GetCMSsRGBTransform(SurfaceFormat::OS_RGBA);
+ }
+ break;
+ case InfoColorSpace::LINKED:
+ default:
+ // Not supported, no color management.
+ MOZ_LOG(sBMPLog, LogLevel::Debug, ("color space type not provided\n"));
+ break;
+ }
+ }
+
+ return Transition::To(State::ALLOCATE_SURFACE, 0);
+}
+
+void nsBMPDecoder::PrepareCalibratedColorProfile() {
+ // BMP does not define a white point. Use the same as sRGB. This matches what
+ // Chrome does as well.
+ qcms_CIE_xyY white_point = qcms_white_point_sRGB();
+
+ qcms_CIE_xyYTRIPLE primaries;
+ float redGamma =
+ CalRbgEndpointToQcms(mH.mColorSpace.mCalibrated.mRed, primaries.red);
+ float greenGamma =
+ CalRbgEndpointToQcms(mH.mColorSpace.mCalibrated.mGreen, primaries.green);
+ float blueGamma =
+ CalRbgEndpointToQcms(mH.mColorSpace.mCalibrated.mBlue, primaries.blue);
+
+ // Explicitly verify the profile because sometimes the values from the BMP
+ // header are just garbage.
+ mInProfile = qcms_profile_create_rgb_with_gamma_set(
+ white_point, primaries, redGamma, greenGamma, blueGamma);
+ if (mInProfile && qcms_profile_is_bogus(mInProfile)) {
+ // Bad profile, just use sRGB instead. Release the profile here, so that
+ // our destructor doesn't assume we are the owner for the transform.
+ qcms_profile_release(mInProfile);
+ mInProfile = nullptr;
+ }
+
+ if (mInProfile) {
+ MOZ_LOG(sBMPLog, LogLevel::Debug, ("using calibrated RGB color profile\n"));
+ PrepareColorProfileTransform();
+ } else {
+ MOZ_LOG(sBMPLog, LogLevel::Debug,
+ ("failed to create calibrated RGB color profile, using sRGB\n"));
+ if (mColors) {
+ // We will transform the color table instead of the output pixels.
+ mTransform = GetCMSsRGBTransform(SurfaceFormat::R8G8B8);
+ } else {
+ mTransform = GetCMSsRGBTransform(SurfaceFormat::OS_RGBA);
+ }
+ }
+}
+
+void nsBMPDecoder::PrepareColorProfileTransform() {
+ if (!mInProfile || !GetCMSOutputProfile()) {
+ return;
+ }
+
+ qcms_data_type inType;
+ qcms_data_type outType;
+ if (mColors) {
+ // We will transform the color table instead of the output pixels.
+ inType = QCMS_DATA_RGB_8;
+ outType = QCMS_DATA_RGB_8;
+ } else {
+ inType = gfxPlatform::GetCMSOSRGBAType();
+ outType = inType;
+ }
+
+ qcms_intent intent;
+ switch (mH.mCsIntent) {
+ case InfoColorIntent::BUSINESS:
+ intent = QCMS_INTENT_SATURATION;
+ break;
+ case InfoColorIntent::GRAPHICS:
+ intent = QCMS_INTENT_RELATIVE_COLORIMETRIC;
+ break;
+ case InfoColorIntent::ABS_COLORIMETRIC:
+ intent = QCMS_INTENT_ABSOLUTE_COLORIMETRIC;
+ break;
+ case InfoColorIntent::IMAGES:
+ default:
+ intent = QCMS_INTENT_PERCEPTUAL;
+ break;
+ }
+
+ mTransform = qcms_transform_create(mInProfile, inType, GetCMSOutputProfile(),
+ outType, intent);
+ if (!mTransform) {
+ MOZ_LOG(sBMPLog, LogLevel::Debug,
+ ("failed to create color profile transform\n"));
+ }
+}
+
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::SeekColorProfile(
+ size_t aLength) {
+ // The offset needs to be at least after the color table.
+ uint32_t offset = mH.mColorSpace.mProfile.mOffset;
+ if (offset <= mH.mBIHSize + aLength + mNumColors * mBytesPerColor ||
+ mH.mColorSpace.mProfile.mLength == 0) {
+ return Transition::To(State::ALLOCATE_SURFACE, 0);
+ }
+
+ // We have already read the header and bitfields.
+ offset -= mH.mBIHSize + aLength;
+
+ // We need to skip ahead to search for the embedded color profile. We want
+ // to return to this point once we read it.
+ mReturnIterator = mLexer.Clone(*mIterator, SIZE_MAX);
+ if (!mReturnIterator) {
+ return Transition::TerminateFailure();
+ }
+
+ return Transition::ToUnbuffered(State::FOUND_COLOR_PROFILE,
+ State::SKIP_TO_COLOR_PROFILE, offset);
+}
+
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadColorProfile(
+ const char* aData, size_t aLength) {
+ mInProfile = qcms_profile_from_memory(aData, aLength);
+ if (mInProfile) {
+ MOZ_LOG(sBMPLog, LogLevel::Debug, ("using embedded color profile\n"));
+ PrepareColorProfileTransform();
+ }
+
+ // Jump back to where we left off.
+ mIterator = std::move(mReturnIterator);
+ return Transition::To(State::ALLOCATE_SURFACE, 0);
+}
+
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::AllocateSurface() {
+ SurfaceFormat format;
+ SurfacePipeFlags pipeFlags = SurfacePipeFlags();
+
+ if (mMayHaveTransparency) {
+ format = SurfaceFormat::OS_RGBA;
+ if (!(GetSurfaceFlags() & SurfaceFlags::NO_PREMULTIPLY_ALPHA)) {
+ pipeFlags |= SurfacePipeFlags::PREMULTIPLY_ALPHA;
+ }
+ } else {
+ format = SurfaceFormat::OS_RGBX;
+ }
+
+ if (mH.mHeight >= 0) {
+ // BMPs store their rows in reverse order, so we may need to flip.
+ pipeFlags |= SurfacePipeFlags::FLIP_VERTICALLY;
+ }
+
+ mRowBuffer.reset(new (fallible) uint32_t[mH.mWidth]);
+ if (!mRowBuffer) {
+ return Transition::TerminateFailure();
+ }
+
+ // Only give the color transform to the SurfacePipe if we are not transforming
+ // the color table in advance.
+ qcms_transform* transform = mColors ? nullptr : mTransform;
+
+ Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
+ this, Size(), OutputSize(), FullFrame(), format, format, Nothing(),
+ transform, pipeFlags);
+ if (!pipe) {
+ return Transition::TerminateFailure();
+ }
+
+ mPipe = std::move(*pipe);
+ ClearRowBufferRemainder();
+ return Transition::To(State::COLOR_TABLE, mNumColors * mBytesPerColor);
+}
+
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadColorTable(
+ const char* aData, size_t aLength) {
+ MOZ_ASSERT_IF(aLength != 0, mNumColors > 0 && mColors);
+
+ mPreGapLength += aLength;
+
+ for (uint32_t i = 0; i < mNumColors; i++) {
+ // The format is BGR or BGR0.
+ mColors[i].mBlue = uint8_t(aData[0]);
+ mColors[i].mGreen = uint8_t(aData[1]);
+ mColors[i].mRed = uint8_t(aData[2]);
+ aData += mBytesPerColor;
+ }
+
+ // If we have a color table and a transform, we can avoid transforming each
+ // pixel by doing the table in advance. We color manage every entry in the
+ // table, even if it is smaller in case the BMP is malformed and overruns
+ // its stated color range.
+ if (mColors && mTransform) {
+ qcms_transform_data(mTransform, mColors.get(), mColors.get(), 256);
+ }
+
+ // If we are decoding a BMP from the clipboard, we did not know the data
+ // offset in advance. It is just defined as after the header and color table.
+ if (mIsForClipboard) {
+ mH.mDataOffset += mPreGapLength;
+ }
+
+ // We know how many bytes we've read so far (mPreGapLength) and we know the
+ // offset of the pixel data (mH.mDataOffset), so we can determine the length
+ // of the gap (possibly zero) between the color table and the pixel data.
+ //
+ // If the gap is negative the file must be malformed (e.g. mH.mDataOffset
+ // points into the middle of the color palette instead of past the end) and
+ // we give up.
+ if (mPreGapLength > mH.mDataOffset) {
+ return Transition::TerminateFailure();
+ }
+
+ uint32_t gapLength = mH.mDataOffset - mPreGapLength;
+
+ return Transition::ToUnbuffered(State::AFTER_GAP, State::GAP, gapLength);
+}
+
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::SkipGap() {
+ return Transition::ContinueUnbuffered(State::GAP);
+}
+
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::AfterGap() {
+ // If there are no pixels we can stop.
+ //
+ // XXX: normally, if there are no pixels we will have stopped decoding before
+ // now, outside of this decoder. However, if the BMP is within an ICO file,
+ // it's possible that the ICO claimed the image had a non-zero size while the
+ // BMP claims otherwise. This test is to catch that awkward case. If we ever
+ // come up with a more general solution to this ICO-and-BMP-disagree-on-size
+ // problem, this test can be removed.
+ if (mH.mWidth == 0 || mH.mHeight == 0) {
+ return Transition::TerminateSuccess();
+ }
+
+ bool hasRLE = mH.mCompression == Compression::RLE8 ||
+ mH.mCompression == Compression::RLE4;
+ return hasRLE ? Transition::To(State::RLE_SEGMENT, RLE::SEGMENT_LENGTH)
+ : Transition::To(State::PIXEL_ROW, mPixelRowSize);
+}
+
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadPixelRow(
+ const char* aData) {
+ MOZ_ASSERT(mCurrentRow > 0);
+ MOZ_ASSERT(mCurrentPos == 0);
+
+ const uint8_t* src = reinterpret_cast<const uint8_t*>(aData);
+ uint32_t* dst = RowBuffer();
+ uint32_t lpos = mH.mWidth;
+ switch (mH.mBpp) {
+ case 1:
+ while (lpos > 0) {
+ int8_t bit;
+ uint8_t idx;
+ for (bit = 7; bit >= 0 && lpos > 0; bit--) {
+ idx = (*src >> bit) & 1;
+ SetPixel(dst, idx, mColors);
+ --lpos;
+ }
+ ++src;
+ }
+ break;
+
+ case 4:
+ while (lpos > 0) {
+ Set4BitPixel(dst, *src, lpos, mColors);
+ ++src;
+ }
+ break;
+
+ case 8:
+ while (lpos > 0) {
+ SetPixel(dst, *src, mColors);
+ --lpos;
+ ++src;
+ }
+ break;
+
+ case 16:
+ if (mBitFields.IsR5G5B5()) {
+ // Specialize this common case.
+ while (lpos > 0) {
+ uint16_t val = LittleEndian::readUint16(src);
+ SetPixel(dst, mBitFields.mRed.Get5(val), mBitFields.mGreen.Get5(val),
+ mBitFields.mBlue.Get5(val));
+ --lpos;
+ src += 2;
+ }
+ } else {
+ bool anyHasAlpha = false;
+ while (lpos > 0) {
+ uint16_t val = LittleEndian::readUint16(src);
+ SetPixel(dst, mBitFields.mRed.Get(val), mBitFields.mGreen.Get(val),
+ mBitFields.mBlue.Get(val),
+ mBitFields.mAlpha.GetAlpha(val, anyHasAlpha));
+ --lpos;
+ src += 2;
+ }
+ if (anyHasAlpha) {
+ MOZ_ASSERT(mMayHaveTransparency);
+ mDoesHaveTransparency = true;
+ }
+ }
+ break;
+
+ case 24:
+ while (lpos > 0) {
+ SetPixel(dst, src[2], src[1], src[0]);
+ --lpos;
+ src += 3;
+ }
+ break;
+
+ case 32:
+ if (mH.mCompression == Compression::RGB && mIsWithinICO &&
+ mH.mBpp == 32) {
+ // This is a special case only used for 32bpp WinBMPv3-ICO files, which
+ // could be in either 0RGB or ARGB format. We start by assuming it's
+ // an 0RGB image. If we hit a non-zero alpha value, then we know it's
+ // actually an ARGB image, and change tack accordingly.
+ // (Note: a fully-transparent ARGB image is indistinguishable from a
+ // 0RGB image, and we will render such an image as a 0RGB image, i.e.
+ // opaquely. This is unlikely to be a problem in practice.)
+ while (lpos > 0) {
+ if (!mDoesHaveTransparency && src[3] != 0) {
+ // Up until now this looked like an 0RGB image, but we now know
+ // it's actually an ARGB image. Which means every pixel we've seen
+ // so far has been fully transparent. So we go back and redo them.
+
+ // Tell the SurfacePipe to go back to the start.
+ mPipe.ResetToFirstRow();
+
+ // Redo the complete rows we've already done.
+ MOZ_ASSERT(mCurrentPos == 0);
+ int32_t currentRow = mCurrentRow;
+ mCurrentRow = AbsoluteHeight();
+ ClearRowBufferRemainder();
+ while (mCurrentRow > currentRow) {
+ FinishRow();
+ }
+
+ // Reset the row pointer back to where we started.
+ dst = RowBuffer() + (mH.mWidth - lpos);
+
+ MOZ_ASSERT(mMayHaveTransparency);
+ mDoesHaveTransparency = true;
+ }
+
+ // If mDoesHaveTransparency is false, treat this as an 0RGB image.
+ // Otherwise, treat this as an ARGB image.
+ SetPixel(dst, src[2], src[1], src[0],
+ mDoesHaveTransparency ? src[3] : 0xff);
+ src += 4;
+ --lpos;
+ }
+ } else if (mBitFields.IsR8G8B8()) {
+ // Specialize this common case.
+ while (lpos > 0) {
+ uint32_t val = LittleEndian::readUint32(src);
+ SetPixel(dst, mBitFields.mRed.Get8(val), mBitFields.mGreen.Get8(val),
+ mBitFields.mBlue.Get8(val));
+ --lpos;
+ src += 4;
+ }
+ } else {
+ bool anyHasAlpha = false;
+ while (lpos > 0) {
+ uint32_t val = LittleEndian::readUint32(src);
+ SetPixel(dst, mBitFields.mRed.Get(val), mBitFields.mGreen.Get(val),
+ mBitFields.mBlue.Get(val),
+ mBitFields.mAlpha.GetAlpha(val, anyHasAlpha));
+ --lpos;
+ src += 4;
+ }
+ if (anyHasAlpha) {
+ MOZ_ASSERT(mMayHaveTransparency);
+ mDoesHaveTransparency = true;
+ }
+ }
+ break;
+
+ default:
+ MOZ_CRASH("Unsupported color depth; earlier check didn't catch it?");
+ }
+
+ FinishRow();
+ return mCurrentRow == 0 ? Transition::TerminateSuccess()
+ : Transition::To(State::PIXEL_ROW, mPixelRowSize);
+}
+
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadRLESegment(
+ const char* aData) {
+ if (mCurrentRow == 0) {
+ return Transition::TerminateSuccess();
+ }
+
+ uint8_t byte1 = uint8_t(aData[0]);
+ uint8_t byte2 = uint8_t(aData[1]);
+
+ if (byte1 != RLE::ESCAPE) {
+ // Encoded mode consists of two bytes: byte1 specifies the number of
+ // consecutive pixels to be drawn using the color index contained in
+ // byte2.
+ //
+ // Work around bitmaps that specify too many pixels.
+ uint32_t pixelsNeeded = std::min<uint32_t>(mH.mWidth - mCurrentPos, byte1);
+ if (pixelsNeeded) {
+ uint32_t* dst = RowBuffer();
+ mCurrentPos += pixelsNeeded;
+ if (mH.mCompression == Compression::RLE8) {
+ do {
+ SetPixel(dst, byte2, mColors);
+ pixelsNeeded--;
+ } while (pixelsNeeded);
+ } else {
+ do {
+ Set4BitPixel(dst, byte2, pixelsNeeded, mColors);
+ } while (pixelsNeeded);
+ }
+ }
+ return Transition::To(State::RLE_SEGMENT, RLE::SEGMENT_LENGTH);
+ }
+
+ if (byte2 == RLE::ESCAPE_EOL) {
+ ClearRowBufferRemainder();
+ mCurrentPos = 0;
+ FinishRow();
+ return mCurrentRow == 0
+ ? Transition::TerminateSuccess()
+ : Transition::To(State::RLE_SEGMENT, RLE::SEGMENT_LENGTH);
+ }
+
+ if (byte2 == RLE::ESCAPE_EOF) {
+ return Transition::TerminateSuccess();
+ }
+
+ if (byte2 == RLE::ESCAPE_DELTA) {
+ return Transition::To(State::RLE_DELTA, RLE::DELTA_LENGTH);
+ }
+
+ // Absolute mode. |byte2| gives the number of pixels. The length depends on
+ // whether it's 4-bit or 8-bit RLE. Also, the length must be even (and zero
+ // padding is used to achieve this when necessary).
+ MOZ_ASSERT(mAbsoluteModeNumPixels == 0);
+ mAbsoluteModeNumPixels = byte2;
+ uint32_t length = byte2;
+ if (mH.mCompression == Compression::RLE4) {
+ length = (length + 1) / 2; // halve, rounding up
+ }
+ if (length & 1) {
+ length++;
+ }
+ return Transition::To(State::RLE_ABSOLUTE, length);
+}
+
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadRLEDelta(
+ const char* aData) {
+ // Delta encoding makes it possible to skip pixels making part of the image
+ // transparent.
+ MOZ_ASSERT(mMayHaveTransparency);
+ mDoesHaveTransparency = true;
+
+ // Clear the skipped pixels. (This clears to the end of the row,
+ // which is perfect if there's a Y delta and harmless if not).
+ ClearRowBufferRemainder();
+
+ // Handle the XDelta.
+ mCurrentPos += uint8_t(aData[0]);
+ if (mCurrentPos > mH.mWidth) {
+ mCurrentPos = mH.mWidth;
+ }
+
+ // Handle the Y Delta.
+ int32_t yDelta = std::min<int32_t>(uint8_t(aData[1]), mCurrentRow);
+ if (yDelta > 0) {
+ // Commit the current row (the first of the skipped rows).
+ FinishRow();
+
+ // Clear and commit the remaining skipped rows. We want to be careful not
+ // to change mCurrentPos here.
+ memset(mRowBuffer.get(), 0, mH.mWidth * sizeof(uint32_t));
+ for (int32_t line = 1; line < yDelta; line++) {
+ FinishRow();
+ }
+ }
+
+ return mCurrentRow == 0
+ ? Transition::TerminateSuccess()
+ : Transition::To(State::RLE_SEGMENT, RLE::SEGMENT_LENGTH);
+}
+
+LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadRLEAbsolute(
+ const char* aData, size_t aLength) {
+ uint32_t n = mAbsoluteModeNumPixels;
+ mAbsoluteModeNumPixels = 0;
+
+ if (mCurrentPos + n > uint32_t(mH.mWidth)) {
+ // Some DIB RLE8 encoders count a padding byte as the absolute mode
+ // pixel number at the end of the row.
+ if (mH.mCompression == Compression::RLE8 && n > 0 && (n & 1) == 0 &&
+ mCurrentPos + n - uint32_t(mH.mWidth) == 1 && aLength > 0 &&
+ aData[aLength - 1] == 0) {
+ n--;
+ } else {
+ // Bad data. Stop decoding; at least part of the image may have been
+ // decoded.
+ return Transition::TerminateSuccess();
+ }
+ }
+
+ // In absolute mode, n represents the number of pixels that follow, each of
+ // which contains the color index of a single pixel.
+ uint32_t* dst = RowBuffer();
+ uint32_t iSrc = 0;
+ uint32_t* oldPos = dst;
+ if (mH.mCompression == Compression::RLE8) {
+ while (n > 0) {
+ SetPixel(dst, aData[iSrc], mColors);
+ n--;
+ iSrc++;
+ }
+ } else {
+ while (n > 0) {
+ Set4BitPixel(dst, aData[iSrc], n, mColors);
+ iSrc++;
+ }
+ }
+ mCurrentPos += dst - oldPos;
+
+ // We should read all the data (unless the last byte is zero padding).
+ MOZ_ASSERT(iSrc == aLength - 1 || iSrc == aLength);
+
+ return Transition::To(State::RLE_SEGMENT, RLE::SEGMENT_LENGTH);
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/decoders/nsBMPDecoder.h b/image/decoders/nsBMPDecoder.h
new file mode 100644
index 0000000000..c7990834b9
--- /dev/null
+++ b/image/decoders/nsBMPDecoder.h
@@ -0,0 +1,285 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_nsBMPDecoder_h
+#define mozilla_image_decoders_nsBMPDecoder_h
+
+#include "BMPHeaders.h"
+#include "Decoder.h"
+#include "gfxColor.h"
+#include "StreamingLexer.h"
+#include "SurfacePipe.h"
+#include "mozilla/UniquePtr.h"
+
+namespace mozilla {
+namespace image {
+
+namespace bmp {
+
+struct CalRgbEndpoint {
+ uint32_t mGamma;
+ uint32_t mX;
+ uint32_t mY;
+ uint32_t mZ;
+};
+
+/// This struct contains the fields from the file header and info header that
+/// we use during decoding. (Excluding bitfields fields, which are kept in
+/// BitFields.)
+struct Header {
+ uint32_t mDataOffset; // Offset to raster data.
+ uint32_t mBIHSize; // Header size.
+ int32_t mWidth; // Image width.
+ int32_t mHeight; // Image height.
+ uint16_t mBpp; // Bits per pixel.
+ uint32_t mCompression; // See struct Compression for valid values.
+ uint32_t mImageSize; // (compressed) image size. Can be 0 if
+ // mCompression==0.
+ uint32_t mNumColors; // Used colors.
+ InfoColorSpace mCsType; // Color space type.
+ InfoColorIntent mCsIntent; // Color space intent.
+
+ union {
+ struct {
+ CalRgbEndpoint mRed;
+ CalRgbEndpoint mGreen;
+ CalRgbEndpoint mBlue;
+ } mCalibrated;
+
+ struct {
+ uint32_t mOffset;
+ uint32_t mLength;
+ } mProfile;
+ } mColorSpace;
+
+ Header()
+ : mDataOffset(0),
+ mBIHSize(0),
+ mWidth(0),
+ mHeight(0),
+ mBpp(0),
+ mCompression(0),
+ mImageSize(0),
+ mNumColors(0),
+ mCsType(InfoColorSpace::SRGB),
+ mCsIntent(InfoColorIntent::IMAGES) {}
+};
+
+/// An entry in the color table.
+struct ColorTableEntry {
+ uint8_t mRed;
+ uint8_t mGreen;
+ uint8_t mBlue;
+};
+
+/// All the color-related bitfields for 16bpp and 32bpp images. We use this
+/// even for older format BMPs that don't have explicit bitfields.
+class BitFields {
+ class Value {
+ friend class BitFields;
+
+ uint32_t mMask; // The mask for the value.
+ uint8_t mRightShift; // The amount to right-shift after masking.
+ uint8_t mBitWidth; // The width (in bits) of the value.
+
+ /// Sets the mask (and thus the right-shift and bit-width as well).
+ void Set(uint32_t aMask);
+
+ public:
+ Value() {
+ mMask = 0;
+ mRightShift = 0;
+ mBitWidth = 0;
+ }
+
+ /// Returns true if this channel is used. Only used for alpha.
+ bool IsPresent() const { return mMask != 0x0; }
+
+ /// Extracts the single color value from the multi-color value.
+ uint8_t Get(uint32_t aVal) const;
+
+ /// Like Get(), but specially for alpha.
+ uint8_t GetAlpha(uint32_t aVal, bool& aHasAlphaOut) const;
+
+ /// Specialized versions of Get() for when the bit-width is 5 or 8.
+ /// (They will assert if called and the bit-width is not 5 or 8.)
+ uint8_t Get5(uint32_t aVal) const;
+ uint8_t Get8(uint32_t aVal) const;
+ };
+
+ public:
+ /// The individual color channels.
+ Value mRed;
+ Value mGreen;
+ Value mBlue;
+ Value mAlpha;
+
+ /// Set bitfields to the standard 5-5-5 16bpp values.
+ void SetR5G5B5();
+
+ /// Set bitfields to the standard 8-8-8 32bpp values.
+ void SetR8G8B8();
+
+ /// Test if bitfields have the standard 5-5-5 16bpp values.
+ bool IsR5G5B5() const;
+
+ /// Test if bitfields have the standard 8-8-8 32bpp values.
+ bool IsR8G8B8() const;
+
+ /// Read the bitfields from a header. The reading of the alpha mask is
+ /// optional.
+ void ReadFromHeader(const char* aData, bool aReadAlpha);
+
+ /// Length of the bitfields structure in the BMP file.
+ static const size_t LENGTH = 12;
+};
+
+} // namespace bmp
+
+class RasterImage;
+
+/// Decoder for BMP-Files, as used by Windows and OS/2.
+
+class nsBMPDecoder : public Decoder {
+ public:
+ ~nsBMPDecoder();
+
+ DecoderType GetType() const override { return DecoderType::BMP; }
+
+ /// @return true if this BMP is a valid ICO resource.
+ bool IsValidICOResource() const override { return true; }
+
+ /// Obtains the internal output image buffer.
+ uint32_t* GetImageData() { return reinterpret_cast<uint32_t*>(mImageData); }
+
+ /// Obtains the length of the internal output image buffer.
+ size_t GetImageDataLength() const { return mImageDataLength; }
+
+ /// Obtains the size of the compressed image resource.
+ int32_t GetCompressedImageSize() const;
+
+ /// Mark this BMP as being within an ICO file. Only used for testing purposes
+ /// because the ICO-specific constructor does this marking automatically.
+ void SetIsWithinICO() { mIsWithinICO = true; }
+
+ /// Did the BMP file have alpha data of any kind? (Only use this after the
+ /// bitmap has been fully decoded.)
+ bool HasTransparency() const { return mDoesHaveTransparency; }
+
+ LexerResult DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) override;
+ nsresult BeforeFinishInternal() override;
+ nsresult FinishInternal() override;
+
+ private:
+ friend class DecoderFactory;
+
+ enum class State {
+ FILE_HEADER,
+ INFO_HEADER_SIZE,
+ INFO_HEADER_REST,
+ BITFIELDS,
+ SKIP_TO_COLOR_PROFILE,
+ FOUND_COLOR_PROFILE,
+ COLOR_PROFILE,
+ ALLOCATE_SURFACE,
+ COLOR_TABLE,
+ GAP,
+ AFTER_GAP,
+ PIXEL_ROW,
+ RLE_SEGMENT,
+ RLE_DELTA,
+ RLE_ABSOLUTE
+ };
+
+ // This is the constructor used for normal and clipboard BMP images.
+ explicit nsBMPDecoder(RasterImage* aImage, bool aForClipboard = false);
+
+ // This is the constructor used for BMP resources in ICO images.
+ nsBMPDecoder(RasterImage* aImage, uint32_t aDataOffset);
+
+ // Helper constructor called by the other two.
+ nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength,
+ bool aForClipboard);
+
+ int32_t AbsoluteHeight() const { return abs(mH.mHeight); }
+
+ uint32_t* RowBuffer();
+ void ClearRowBufferRemainder();
+
+ void FinishRow();
+
+ void PrepareCalibratedColorProfile();
+ void PrepareColorProfileTransform();
+
+ LexerTransition<State> ReadFileHeader(const char* aData, size_t aLength);
+ LexerTransition<State> ReadInfoHeaderSize(const char* aData, size_t aLength);
+ LexerTransition<State> ReadInfoHeaderRest(const char* aData, size_t aLength);
+ LexerTransition<State> ReadBitfields(const char* aData, size_t aLength);
+ LexerTransition<State> SeekColorProfile(size_t aLength);
+ LexerTransition<State> ReadColorProfile(const char* aData, size_t aLength);
+ LexerTransition<State> AllocateSurface();
+ LexerTransition<State> ReadColorTable(const char* aData, size_t aLength);
+ LexerTransition<State> SkipGap();
+ LexerTransition<State> AfterGap();
+ LexerTransition<State> ReadPixelRow(const char* aData);
+ LexerTransition<State> ReadRLESegment(const char* aData);
+ LexerTransition<State> ReadRLEDelta(const char* aData);
+ LexerTransition<State> ReadRLEAbsolute(const char* aData, size_t aLength);
+
+ SurfacePipe mPipe;
+
+ StreamingLexer<State> mLexer;
+
+ // Iterator to save return point.
+ Maybe<SourceBufferIterator> mReturnIterator;
+
+ UniquePtr<uint32_t[]> mRowBuffer;
+
+ bmp::Header mH;
+
+ // If the BMP is within an ICO file our treatment of it differs slightly.
+ bool mIsWithinICO;
+
+ // If the BMP decoded from the clipboard, we don't start with a data offset.
+ bool mIsForClipboard;
+
+ bmp::BitFields mBitFields;
+
+ // Might the image have transparency? Determined from the headers during
+ // metadata decode. (Does not guarantee the image actually has transparency.)
+ bool mMayHaveTransparency;
+
+ // Does the image have transparency? Determined during full decoding, so only
+ // use this after that has been completed.
+ bool mDoesHaveTransparency;
+
+ uint32_t mNumColors; // The number of used colors, i.e. the number of
+ // entries in mColors, if it's present.
+ UniquePtr<bmp::ColorTableEntry[]>
+ mColors; // The color table, if it's present.
+ uint32_t mBytesPerColor; // 3 or 4, depending on the format
+
+ // The number of bytes prior to the optional gap that have been read. This
+ // is used to find the start of the pixel data.
+ uint32_t mPreGapLength;
+
+ uint32_t mPixelRowSize; // The number of bytes per pixel row.
+
+ int32_t mCurrentRow; // Index of the row of the image that's currently
+ // being decoded: [height,1].
+ int32_t mCurrentPos; // Index into the current line. Used when
+ // doing RLE decoding and when filling in pixels
+ // for truncated files.
+
+ // Only used in RLE_ABSOLUTE state: the number of pixels to read.
+ uint32_t mAbsoluteModeNumPixels;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_decoders_nsBMPDecoder_h
diff --git a/image/decoders/nsGIFDecoder2.cpp b/image/decoders/nsGIFDecoder2.cpp
new file mode 100644
index 0000000000..9b2de9124a
--- /dev/null
+++ b/image/decoders/nsGIFDecoder2.cpp
@@ -0,0 +1,1073 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+The Graphics Interchange Format(c) is the copyright property of CompuServe
+Incorporated. Only CompuServe Incorporated is authorized to define, redefine,
+enhance, alter, modify or change in any way the definition of the format.
+
+CompuServe Incorporated hereby grants a limited, non-exclusive, royalty-free
+license for the use of the Graphics Interchange Format(sm) in computer
+software; computer software utilizing GIF(sm) must acknowledge ownership of the
+Graphics Interchange Format and its Service Mark by CompuServe Incorporated, in
+User and Technical Documentation. Computer software utilizing GIF, which is
+distributed or may be distributed without User or Technical Documentation must
+display to the screen or printer a message acknowledging ownership of the
+Graphics Interchange Format and the Service Mark by CompuServe Incorporated; in
+this case, the acknowledgement may be displayed in an opening screen or leading
+banner, or a closing screen or trailing banner. A message such as the following
+may be used:
+
+ "The Graphics Interchange Format(c) is the Copyright property of
+ CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ CompuServe Incorporated."
+
+For further information, please contact :
+
+ CompuServe Incorporated
+ Graphics Technology Department
+ 5000 Arlington Center Boulevard
+ Columbus, Ohio 43220
+ U. S. A.
+
+CompuServe Incorporated maintains a mailing list with all those individuals and
+organizations who wish to receive copies of this document when it is corrected
+or revised. This service is offered free of charge; please provide us with your
+mailing address.
+*/
+
+#include "nsGIFDecoder2.h"
+
+#include <stddef.h>
+
+#include "imgFrame.h"
+#include "mozilla/EndianUtils.h"
+#include "RasterImage.h"
+#include "SurfacePipeFactory.h"
+
+#include "gfxColor.h"
+#include "gfxPlatform.h"
+#include "qcms.h"
+#include <algorithm>
+#include "mozilla/Telemetry.h"
+
+using namespace mozilla::gfx;
+
+using std::max;
+
+namespace mozilla {
+namespace image {
+
+//////////////////////////////////////////////////////////////////////
+// GIF Decoder Implementation
+
+static const size_t GIF_HEADER_LEN = 6;
+static const size_t GIF_SCREEN_DESCRIPTOR_LEN = 7;
+static const size_t BLOCK_HEADER_LEN = 1;
+static const size_t SUB_BLOCK_HEADER_LEN = 1;
+static const size_t EXTENSION_HEADER_LEN = 2;
+static const size_t GRAPHIC_CONTROL_EXTENSION_LEN = 4;
+static const size_t APPLICATION_EXTENSION_LEN = 11;
+static const size_t IMAGE_DESCRIPTOR_LEN = 9;
+
+// Masks for reading color table information from packed fields in the screen
+// descriptor and image descriptor blocks.
+static const uint8_t PACKED_FIELDS_COLOR_TABLE_BIT = 0x80;
+static const uint8_t PACKED_FIELDS_INTERLACED_BIT = 0x40;
+static const uint8_t PACKED_FIELDS_TABLE_DEPTH_MASK = 0x07;
+
+nsGIFDecoder2::nsGIFDecoder2(RasterImage* aImage)
+ : Decoder(aImage),
+ mLexer(Transition::To(State::GIF_HEADER, GIF_HEADER_LEN),
+ Transition::TerminateSuccess()),
+ mOldColor(0),
+ mCurrentFrameIndex(-1),
+ mColorTablePos(0),
+ mColormap(nullptr),
+ mColormapSize(0),
+ mColorMask('\0'),
+ mGIFOpen(false),
+ mSawTransparency(false),
+ mSwizzleFn(nullptr) {
+ // Clear out the structure, excluding the arrays. Ensure that the global
+ // colormap is initialized as opaque.
+ memset(&mGIFStruct, 0, sizeof(mGIFStruct));
+ memset(mGIFStruct.global_colormap, 0xFF, sizeof(mGIFStruct.global_colormap));
+
+ // Each color table will need to be unpacked.
+ mSwizzleFn = SwizzleRow(SurfaceFormat::R8G8B8, SurfaceFormat::OS_RGBA);
+ MOZ_ASSERT(mSwizzleFn);
+}
+
+nsGIFDecoder2::~nsGIFDecoder2() { free(mGIFStruct.local_colormap); }
+
+nsresult nsGIFDecoder2::FinishInternal() {
+ MOZ_ASSERT(!HasError(), "Shouldn't call FinishInternal after error!");
+
+ // If the GIF got cut off, handle it anyway
+ if (!IsMetadataDecode() && mGIFOpen) {
+ if (mCurrentFrameIndex == mGIFStruct.images_decoded) {
+ EndImageFrame();
+ }
+ PostDecodeDone(mGIFStruct.loop_count);
+ mGIFOpen = false;
+ }
+
+ return NS_OK;
+}
+
+void nsGIFDecoder2::FlushImageData() {
+ Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect();
+ if (!invalidRect) {
+ return;
+ }
+
+ PostInvalidation(invalidRect->mInputSpaceRect,
+ Some(invalidRect->mOutputSpaceRect));
+}
+
+//******************************************************************************
+// GIF decoder callback methods. Part of public API for GIF2
+//******************************************************************************
+
+//******************************************************************************
+void nsGIFDecoder2::BeginGIF() {
+ if (mGIFOpen) {
+ return;
+ }
+
+ mGIFOpen = true;
+
+ PostSize(mGIFStruct.screen_width, mGIFStruct.screen_height);
+}
+
+bool nsGIFDecoder2::CheckForTransparency(const OrientedIntRect& aFrameRect) {
+ // Check if the image has a transparent color in its palette.
+ if (mGIFStruct.is_transparent) {
+ PostHasTransparency();
+ return true;
+ }
+
+ // This is a bit of a hack. Some sites will use a 1x1 gif that includes no
+ // header information indicating it is transparent, no palette, and no image
+ // data at all (so no pixels get written) to represent a transparent pixel
+ // using the absolute least number of bytes. Generally things are setup to
+ // detect transparency without decoding the image data. So to detect this kind
+ // of transparency without decoing the image data we would have to assume
+ // every gif is transparent, which we would like to avoid. Changing things so
+ // that we can detect transparency at any point of decoding is a bigger change
+ // and not worth it for one questionable 1x1 gif. Using this "trick" for
+ // anything but 1x1 transparent spacer gifs doesn't make sense, so it's
+ // reasonable to target 1x1 gifs just for this.
+ if (mGIFStruct.screen_width == 1 && mGIFStruct.screen_height == 1) {
+ PostHasTransparency();
+ return true;
+ }
+
+ if (mGIFStruct.images_decoded > 0) {
+ return false; // We only care about first frame padding below.
+ }
+
+ // If we need padding on the first frame, that means we don't draw into part
+ // of the image at all. Report that as transparency.
+ OrientedIntRect imageRect(0, 0, mGIFStruct.screen_width,
+ mGIFStruct.screen_height);
+ if (!imageRect.IsEqualEdges(aFrameRect)) {
+ PostHasTransparency();
+ mSawTransparency = true; // Make sure we don't optimize it away.
+ return true;
+ }
+
+ return false;
+}
+
+//******************************************************************************
+nsresult nsGIFDecoder2::BeginImageFrame(const OrientedIntRect& aFrameRect,
+ uint16_t aDepth, bool aIsInterlaced) {
+ MOZ_ASSERT(HasSize());
+
+ bool hasTransparency = CheckForTransparency(aFrameRect);
+
+ // Make sure there's no animation if we're downscaling.
+ MOZ_ASSERT_IF(Size() != OutputSize(), !GetImageMetadata().HasAnimation());
+
+ Maybe<AnimationParams> animParams;
+ if (!IsFirstFrameDecode()) {
+ animParams.emplace(aFrameRect.ToUnknownRect(),
+ FrameTimeout::FromRawMilliseconds(mGIFStruct.delay_time),
+ uint32_t(mGIFStruct.images_decoded), BlendMethod::OVER,
+ DisposalMethod(mGIFStruct.disposal_method));
+ }
+
+ SurfacePipeFlags pipeFlags =
+ aIsInterlaced ? SurfacePipeFlags::DEINTERLACE : SurfacePipeFlags();
+
+ gfx::SurfaceFormat format;
+ if (mGIFStruct.images_decoded == 0) {
+ // The first frame may be displayed progressively.
+ pipeFlags |= SurfacePipeFlags::PROGRESSIVE_DISPLAY;
+
+ // Only allow opaque surfaces if we are decoding a single image without
+ // transparency. For an animation, there isn't much benefit to RGBX given
+ // the current frame is constantly changing, and there are many risks
+ // since BlendAnimationFilter is able to clear rows of data.
+ format = hasTransparency || animParams ? SurfaceFormat::OS_RGBA
+ : SurfaceFormat::OS_RGBX;
+ } else {
+ format = SurfaceFormat::OS_RGBA;
+ }
+
+ Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
+ this, Size(), OutputSize(), aFrameRect, format, format, animParams,
+ mTransform, pipeFlags);
+ mCurrentFrameIndex = mGIFStruct.images_decoded;
+
+ if (!pipe) {
+ mPipe = SurfacePipe();
+ return NS_ERROR_FAILURE;
+ }
+
+ mPipe = std::move(*pipe);
+ return NS_OK;
+}
+
+//******************************************************************************
+void nsGIFDecoder2::EndImageFrame() {
+ Opacity opacity = Opacity::SOME_TRANSPARENCY;
+
+ if (mGIFStruct.images_decoded == 0) {
+ // We need to send invalidations for the first frame.
+ FlushImageData();
+
+ // The first frame was preallocated with alpha; if it wasn't transparent, we
+ // should fix that. We can also mark it opaque unconditionally if we didn't
+ // actually see any transparent pixels - this test is only valid for the
+ // first frame.
+ if (!mGIFStruct.is_transparent && !mSawTransparency) {
+ opacity = Opacity::FULLY_OPAQUE;
+ }
+ }
+
+ // Unconditionally increment images_decoded, because we unconditionally
+ // append frames in BeginImageFrame(). This ensures that images_decoded
+ // always refers to the frame in mImage we're currently decoding,
+ // even if some of them weren't decoded properly and thus are blank.
+ mGIFStruct.images_decoded++;
+
+ // Reset graphic control extension parameters that we shouldn't reuse
+ // between frames.
+ mGIFStruct.delay_time = 0;
+
+ // Tell the superclass we finished a frame
+ PostFrameStop(opacity);
+
+ // Reset the transparent pixel
+ if (mOldColor) {
+ mColormap[mGIFStruct.tpixel] = mOldColor;
+ mOldColor = 0;
+ }
+
+ mColormap = nullptr;
+ mColormapSize = 0;
+ mCurrentFrameIndex = -1;
+}
+
+template <typename PixelSize>
+PixelSize nsGIFDecoder2::ColormapIndexToPixel(uint8_t aIndex) {
+ MOZ_ASSERT(sizeof(PixelSize) == sizeof(uint32_t));
+
+ // Retrieve the next color, clamping to the size of the colormap.
+ uint32_t color = mColormap[aIndex & mColorMask];
+
+ // Check for transparency.
+ if (mGIFStruct.is_transparent) {
+ mSawTransparency = mSawTransparency || color == 0;
+ }
+
+ return color;
+}
+
+template <>
+uint8_t nsGIFDecoder2::ColormapIndexToPixel<uint8_t>(uint8_t aIndex) {
+ return aIndex & mColorMask;
+}
+
+template <typename PixelSize>
+std::tuple<int32_t, Maybe<WriteState>> nsGIFDecoder2::YieldPixels(
+ const uint8_t* aData, size_t aLength, size_t* aBytesReadOut,
+ PixelSize* aPixelBlock, int32_t aBlockSize) {
+ MOZ_ASSERT(aData);
+ MOZ_ASSERT(aBytesReadOut);
+ MOZ_ASSERT(mGIFStruct.stackp >= mGIFStruct.stack);
+
+ // Advance to the next byte we should read.
+ const uint8_t* data = aData + *aBytesReadOut;
+
+ int32_t written = 0;
+ while (aBlockSize > written) {
+ // If we don't have any decoded data to yield, try to read some input and
+ // produce some.
+ if (mGIFStruct.stackp == mGIFStruct.stack) {
+ while (mGIFStruct.bits < mGIFStruct.codesize &&
+ *aBytesReadOut < aLength) {
+ // Feed the next byte into the decoder's 32-bit input buffer.
+ mGIFStruct.datum += int32_t(*data) << mGIFStruct.bits;
+ mGIFStruct.bits += 8;
+ data += 1;
+ *aBytesReadOut += 1;
+ }
+
+ if (mGIFStruct.bits < mGIFStruct.codesize) {
+ return std::make_tuple(written, Some(WriteState::NEED_MORE_DATA));
+ }
+
+ // Get the leading variable-length symbol from the data stream.
+ int code = mGIFStruct.datum & mGIFStruct.codemask;
+ mGIFStruct.datum >>= mGIFStruct.codesize;
+ mGIFStruct.bits -= mGIFStruct.codesize;
+
+ const int clearCode = ClearCode();
+
+ // Reset the dictionary to its original state, if requested
+ if (code == clearCode) {
+ mGIFStruct.codesize = mGIFStruct.datasize + 1;
+ mGIFStruct.codemask = (1 << mGIFStruct.codesize) - 1;
+ mGIFStruct.avail = clearCode + 2;
+ mGIFStruct.oldcode = -1;
+ return std::make_tuple(written, Some(WriteState::NEED_MORE_DATA));
+ }
+
+ // Check for explicit end-of-stream code. It should only appear after all
+ // image data, but if that was the case we wouldn't be in this function,
+ // so this is always an error condition.
+ if (code == (clearCode + 1)) {
+ return std::make_tuple(written, Some(WriteState::FAILURE));
+ }
+
+ if (mGIFStruct.oldcode == -1) {
+ if (code >= MAX_BITS) {
+ // The code's too big; something's wrong.
+ return std::make_tuple(written, Some(WriteState::FAILURE));
+ }
+
+ mGIFStruct.firstchar = mGIFStruct.oldcode = code;
+
+ // Yield a pixel at the appropriate index in the colormap.
+ mGIFStruct.pixels_remaining--;
+ aPixelBlock[written++] =
+ ColormapIndexToPixel<PixelSize>(mGIFStruct.suffix[code]);
+ continue;
+ }
+
+ int incode = code;
+ if (code >= mGIFStruct.avail) {
+ *mGIFStruct.stackp++ = mGIFStruct.firstchar;
+ code = mGIFStruct.oldcode;
+
+ if (mGIFStruct.stackp >= mGIFStruct.stack + MAX_BITS) {
+ // Stack overflow; something's wrong.
+ return std::make_tuple(written, Some(WriteState::FAILURE));
+ }
+ }
+
+ while (code >= clearCode) {
+ if ((code >= MAX_BITS) || (code == mGIFStruct.prefix[code])) {
+ return std::make_tuple(written, Some(WriteState::FAILURE));
+ }
+
+ *mGIFStruct.stackp++ = mGIFStruct.suffix[code];
+ code = mGIFStruct.prefix[code];
+
+ if (mGIFStruct.stackp >= mGIFStruct.stack + MAX_BITS) {
+ // Stack overflow; something's wrong.
+ return std::make_tuple(written, Some(WriteState::FAILURE));
+ }
+ }
+
+ *mGIFStruct.stackp++ = mGIFStruct.firstchar = mGIFStruct.suffix[code];
+
+ // Define a new codeword in the dictionary.
+ if (mGIFStruct.avail < 4096) {
+ mGIFStruct.prefix[mGIFStruct.avail] = mGIFStruct.oldcode;
+ mGIFStruct.suffix[mGIFStruct.avail] = mGIFStruct.firstchar;
+ mGIFStruct.avail++;
+
+ // If we've used up all the codewords of a given length increase the
+ // length of codewords by one bit, but don't exceed the specified
+ // maximum codeword size of 12 bits.
+ if (((mGIFStruct.avail & mGIFStruct.codemask) == 0) &&
+ (mGIFStruct.avail < 4096)) {
+ mGIFStruct.codesize++;
+ mGIFStruct.codemask += mGIFStruct.avail;
+ }
+ }
+
+ mGIFStruct.oldcode = incode;
+ }
+
+ if (MOZ_UNLIKELY(mGIFStruct.stackp <= mGIFStruct.stack)) {
+ MOZ_ASSERT_UNREACHABLE("No decoded data but we didn't return early?");
+ return std::make_tuple(written, Some(WriteState::FAILURE));
+ }
+
+ // Yield a pixel at the appropriate index in the colormap.
+ mGIFStruct.pixels_remaining--;
+ aPixelBlock[written++] =
+ ColormapIndexToPixel<PixelSize>(*--mGIFStruct.stackp);
+ }
+
+ return std::make_tuple(written, Maybe<WriteState>());
+}
+
+/// Expand the colormap from RGB to Packed ARGB as needed by Cairo.
+/// And apply any LCMS transformation.
+void nsGIFDecoder2::ConvertColormap(uint32_t* aColormap, uint32_t aColors) {
+ if (!aColors) {
+ return;
+ }
+
+ // Apply CMS transformation if enabled and available
+ if (mCMSMode == CMSMode::All) {
+ qcms_transform* transform = GetCMSsRGBTransform(SurfaceFormat::R8G8B8);
+ if (transform) {
+ qcms_transform_data(transform, aColormap, aColormap, aColors);
+ }
+ }
+
+ // Expand color table from RGB to BGRA.
+ MOZ_ASSERT(mSwizzleFn);
+ uint8_t* data = reinterpret_cast<uint8_t*>(aColormap);
+ mSwizzleFn(data, data, aColors);
+}
+
+LexerResult nsGIFDecoder2::DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) {
+ MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
+
+ return mLexer.Lex(
+ aIterator, aOnResume,
+ [=](State aState, const char* aData, size_t aLength) {
+ switch (aState) {
+ case State::GIF_HEADER:
+ return ReadGIFHeader(aData);
+ case State::SCREEN_DESCRIPTOR:
+ return ReadScreenDescriptor(aData);
+ case State::GLOBAL_COLOR_TABLE:
+ return ReadGlobalColorTable(aData, aLength);
+ case State::FINISHED_GLOBAL_COLOR_TABLE:
+ return FinishedGlobalColorTable();
+ case State::BLOCK_HEADER:
+ return ReadBlockHeader(aData);
+ case State::EXTENSION_HEADER:
+ return ReadExtensionHeader(aData);
+ case State::GRAPHIC_CONTROL_EXTENSION:
+ return ReadGraphicControlExtension(aData);
+ case State::APPLICATION_IDENTIFIER:
+ return ReadApplicationIdentifier(aData);
+ case State::NETSCAPE_EXTENSION_SUB_BLOCK:
+ return ReadNetscapeExtensionSubBlock(aData);
+ case State::NETSCAPE_EXTENSION_DATA:
+ return ReadNetscapeExtensionData(aData);
+ case State::IMAGE_DESCRIPTOR:
+ return ReadImageDescriptor(aData);
+ case State::FINISH_IMAGE_DESCRIPTOR:
+ return FinishImageDescriptor(aData);
+ case State::LOCAL_COLOR_TABLE:
+ return ReadLocalColorTable(aData, aLength);
+ case State::FINISHED_LOCAL_COLOR_TABLE:
+ return FinishedLocalColorTable();
+ case State::IMAGE_DATA_BLOCK:
+ return ReadImageDataBlock(aData);
+ case State::IMAGE_DATA_SUB_BLOCK:
+ return ReadImageDataSubBlock(aData);
+ case State::LZW_DATA:
+ return ReadLZWData(aData, aLength);
+ case State::SKIP_LZW_DATA:
+ return Transition::ContinueUnbuffered(State::SKIP_LZW_DATA);
+ case State::FINISHED_LZW_DATA:
+ return Transition::To(State::IMAGE_DATA_SUB_BLOCK,
+ SUB_BLOCK_HEADER_LEN);
+ case State::SKIP_SUB_BLOCKS:
+ return SkipSubBlocks(aData);
+ case State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS:
+ return Transition::ContinueUnbuffered(
+ State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS);
+ case State::FINISHED_SKIPPING_DATA:
+ return Transition::To(State::SKIP_SUB_BLOCKS, SUB_BLOCK_HEADER_LEN);
+ default:
+ MOZ_CRASH("Unknown State");
+ }
+ });
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadGIFHeader(
+ const char* aData) {
+ // We retrieve the version here but because many GIF encoders set header
+ // fields incorrectly, we barely use it; features which should only appear in
+ // GIF89a are always accepted.
+ if (strncmp(aData, "GIF87a", GIF_HEADER_LEN) == 0) {
+ mGIFStruct.version = 87;
+ } else if (strncmp(aData, "GIF89a", GIF_HEADER_LEN) == 0) {
+ mGIFStruct.version = 89;
+ } else {
+ return Transition::TerminateFailure();
+ }
+
+ return Transition::To(State::SCREEN_DESCRIPTOR, GIF_SCREEN_DESCRIPTOR_LEN);
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadScreenDescriptor(
+ const char* aData) {
+ mGIFStruct.screen_width = LittleEndian::readUint16(aData + 0);
+ mGIFStruct.screen_height = LittleEndian::readUint16(aData + 2);
+
+ const uint8_t packedFields = aData[4];
+
+ // XXX: Should we be capturing these values even if there is no global color
+ // table?
+ mGIFStruct.global_colormap_depth =
+ (packedFields & PACKED_FIELDS_TABLE_DEPTH_MASK) + 1;
+ mGIFStruct.global_colormap_count = 1 << mGIFStruct.global_colormap_depth;
+
+ // We ignore several fields in the header. We don't care about the 'sort
+ // flag', which indicates if the global color table's entries are sorted in
+ // order of importance - if we need to render this image for a device with a
+ // narrower color gamut than GIF supports we'll handle that at a different
+ // layer. We have no use for the pixel aspect ratio as well. Finally, we
+ // intentionally ignore the background color index, as implementing that
+ // feature would not be web compatible - when a GIF image frame doesn't cover
+ // the entire area of the image, the area that's not covered should always be
+ // transparent.
+
+ if (packedFields & PACKED_FIELDS_COLOR_TABLE_BIT) {
+ MOZ_ASSERT(mColorTablePos == 0);
+
+ // We read the global color table in unbuffered mode since it can be quite
+ // large and it'd be preferable to avoid unnecessary copies.
+ const size_t globalColorTableSize = 3 * mGIFStruct.global_colormap_count;
+ return Transition::ToUnbuffered(State::FINISHED_GLOBAL_COLOR_TABLE,
+ State::GLOBAL_COLOR_TABLE,
+ globalColorTableSize);
+ }
+
+ return Transition::To(State::BLOCK_HEADER, BLOCK_HEADER_LEN);
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadGlobalColorTable(
+ const char* aData, size_t aLength) {
+ uint8_t* dest =
+ reinterpret_cast<uint8_t*>(mGIFStruct.global_colormap) + mColorTablePos;
+ memcpy(dest, aData, aLength);
+ mColorTablePos += aLength;
+ return Transition::ContinueUnbuffered(State::GLOBAL_COLOR_TABLE);
+}
+
+LexerTransition<nsGIFDecoder2::State>
+nsGIFDecoder2::FinishedGlobalColorTable() {
+ ConvertColormap(mGIFStruct.global_colormap, mGIFStruct.global_colormap_count);
+ mColorTablePos = 0;
+ return Transition::To(State::BLOCK_HEADER, BLOCK_HEADER_LEN);
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadBlockHeader(
+ const char* aData) {
+ // Determine what type of block we're dealing with.
+ switch (aData[0]) {
+ case GIF_EXTENSION_INTRODUCER:
+ return Transition::To(State::EXTENSION_HEADER, EXTENSION_HEADER_LEN);
+
+ case GIF_IMAGE_SEPARATOR:
+ return Transition::To(State::IMAGE_DESCRIPTOR, IMAGE_DESCRIPTOR_LEN);
+
+ case GIF_TRAILER:
+ FinishInternal();
+ return Transition::TerminateSuccess();
+
+ default:
+ // If we get anything other than GIF_IMAGE_SEPARATOR,
+ // GIF_EXTENSION_INTRODUCER, or GIF_TRAILER, there is extraneous data
+ // between blocks. The GIF87a spec tells us to keep reading until we find
+ // an image separator, but GIF89a says such a file is corrupt. We follow
+ // GIF89a and bail out.
+
+ if (mGIFStruct.images_decoded > 0) {
+ // The file is corrupt, but we successfully decoded some frames, so we
+ // may as well consider the decode successful and display them.
+ FinishInternal();
+ return Transition::TerminateSuccess();
+ }
+
+ // No images decoded; there is nothing to display.
+ return Transition::TerminateFailure();
+ }
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadExtensionHeader(
+ const char* aData) {
+ const uint8_t label = aData[0];
+ const uint8_t extensionHeaderLength = aData[1];
+
+ // If the extension header is zero length, just treat it as a block terminator
+ // and move on to the next block immediately.
+ if (extensionHeaderLength == 0) {
+ return Transition::To(State::BLOCK_HEADER, BLOCK_HEADER_LEN);
+ }
+
+ switch (label) {
+ case GIF_GRAPHIC_CONTROL_LABEL:
+ // The GIF spec mandates that the Control Extension header block length is
+ // 4 bytes, and the parser for this block reads 4 bytes, so we must
+ // enforce that the buffer contains at least this many bytes. If the GIF
+ // specifies a different length, we allow that, so long as it's larger;
+ // the additional data will simply be ignored.
+ return Transition::To(
+ State::GRAPHIC_CONTROL_EXTENSION,
+ max<uint8_t>(extensionHeaderLength, GRAPHIC_CONTROL_EXTENSION_LEN));
+
+ case GIF_APPLICATION_EXTENSION_LABEL:
+ // Again, the spec specifies that an application extension header is 11
+ // bytes, but for compatibility with GIFs in the wild, we allow deviation
+ // from the spec. This is important for real-world compatibility, as GIFs
+ // in the wild exist with application extension headers that are both
+ // shorter and longer than 11 bytes. However, we only try to actually
+ // interpret the application extension if the length is correct;
+ // otherwise, we just skip the block unconditionally.
+ return extensionHeaderLength == APPLICATION_EXTENSION_LEN
+ ? Transition::To(State::APPLICATION_IDENTIFIER,
+ extensionHeaderLength)
+ : Transition::ToUnbuffered(
+ State::FINISHED_SKIPPING_DATA,
+ State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS,
+ extensionHeaderLength);
+
+ default:
+ // Skip over any other type of extension block, including comment and
+ // plain text blocks.
+ return Transition::ToUnbuffered(State::FINISHED_SKIPPING_DATA,
+ State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS,
+ extensionHeaderLength);
+ }
+}
+
+LexerTransition<nsGIFDecoder2::State>
+nsGIFDecoder2::ReadGraphicControlExtension(const char* aData) {
+ mGIFStruct.is_transparent = aData[0] & 0x1;
+ mGIFStruct.tpixel = uint8_t(aData[3]);
+ mGIFStruct.disposal_method = (aData[0] >> 2) & 0x7;
+
+ if (mGIFStruct.disposal_method == 4) {
+ // Some encoders (and apparently some specs) represent
+ // DisposalMethod::RESTORE_PREVIOUS as 4, but 3 is used in the canonical
+ // spec and is more popular, so we normalize to 3.
+ mGIFStruct.disposal_method = 3;
+ } else if (mGIFStruct.disposal_method > 4) {
+ // This GIF is using a disposal method which is undefined in the spec.
+ // Treat it as DisposalMethod::NOT_SPECIFIED.
+ mGIFStruct.disposal_method = 0;
+ }
+
+ DisposalMethod method = DisposalMethod(mGIFStruct.disposal_method);
+ if (method == DisposalMethod::CLEAR_ALL || method == DisposalMethod::CLEAR) {
+ // We may have to display the background under this image during animation
+ // playback, so we regard it as transparent.
+ PostHasTransparency();
+ }
+
+ mGIFStruct.delay_time = LittleEndian::readUint16(aData + 1) * 10;
+ if (!HasAnimation() && mGIFStruct.delay_time > 0) {
+ PostIsAnimated(FrameTimeout::FromRawMilliseconds(mGIFStruct.delay_time));
+ }
+
+ return Transition::To(State::SKIP_SUB_BLOCKS, SUB_BLOCK_HEADER_LEN);
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadApplicationIdentifier(
+ const char* aData) {
+ if ((strncmp(aData, "NETSCAPE2.0", 11) == 0) ||
+ (strncmp(aData, "ANIMEXTS1.0", 11) == 0)) {
+ // This is a Netscape application extension block.
+ return Transition::To(State::NETSCAPE_EXTENSION_SUB_BLOCK,
+ SUB_BLOCK_HEADER_LEN);
+ }
+
+ // This is an application extension we don't care about. Just skip it.
+ return Transition::To(State::SKIP_SUB_BLOCKS, SUB_BLOCK_HEADER_LEN);
+}
+
+LexerTransition<nsGIFDecoder2::State>
+nsGIFDecoder2::ReadNetscapeExtensionSubBlock(const char* aData) {
+ const uint8_t blockLength = aData[0];
+ if (blockLength == 0) {
+ // We hit the block terminator.
+ return Transition::To(State::BLOCK_HEADER, BLOCK_HEADER_LEN);
+ }
+
+ // We consume a minimum of 3 bytes in accordance with the specs for the
+ // Netscape application extension block, such as they are.
+ const size_t extensionLength = max<uint8_t>(blockLength, 3);
+ return Transition::To(State::NETSCAPE_EXTENSION_DATA, extensionLength);
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadNetscapeExtensionData(
+ const char* aData) {
+ // Documentation for NETSCAPE2.0 / ANIMEXTS1.0 extensions can be found at:
+ // https://wiki.whatwg.org/wiki/GIF
+ static const uint8_t NETSCAPE_LOOPING_EXTENSION_SUB_BLOCK_ID = 1;
+ static const uint8_t NETSCAPE_BUFFERING_EXTENSION_SUB_BLOCK_ID = 2;
+
+ const uint8_t subBlockID = aData[0] & 7;
+ switch (subBlockID) {
+ case NETSCAPE_LOOPING_EXTENSION_SUB_BLOCK_ID:
+ // This is looping extension.
+ mGIFStruct.loop_count = LittleEndian::readUint16(aData + 1);
+ // Zero loop count is infinite animation loop request.
+ if (mGIFStruct.loop_count == 0) {
+ mGIFStruct.loop_count = -1;
+ }
+
+ return Transition::To(State::NETSCAPE_EXTENSION_SUB_BLOCK,
+ SUB_BLOCK_HEADER_LEN);
+
+ case NETSCAPE_BUFFERING_EXTENSION_SUB_BLOCK_ID:
+ // We allow, but ignore, this extension.
+ return Transition::To(State::NETSCAPE_EXTENSION_SUB_BLOCK,
+ SUB_BLOCK_HEADER_LEN);
+
+ default:
+ return Transition::TerminateFailure();
+ }
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadImageDescriptor(
+ const char* aData) {
+ // On the first frame, we don't need to yield, and none of the other checks
+ // below apply, so we can just jump right into FinishImageDescriptor().
+ if (mGIFStruct.images_decoded == 0) {
+ return FinishImageDescriptor(aData);
+ }
+
+ if (!HasAnimation()) {
+ // We should've already called PostIsAnimated(); this must be a corrupt
+ // animated image with a first frame timeout of zero. Signal that we're
+ // animated now, before the first-frame decode early exit below, so that
+ // RasterImage can detect that this happened.
+ PostIsAnimated(FrameTimeout::FromRawMilliseconds(0));
+ }
+
+ if (IsFirstFrameDecode()) {
+ // We're about to get a second frame, but we only want the first. Stop
+ // decoding now.
+ FinishInternal();
+ return Transition::TerminateSuccess();
+ }
+
+ MOZ_ASSERT(Size() == OutputSize(), "Downscaling an animated image?");
+
+ // Yield to allow access to the previous frame before we start a new one.
+ return Transition::ToAfterYield(State::FINISH_IMAGE_DESCRIPTOR);
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::FinishImageDescriptor(
+ const char* aData) {
+ OrientedIntRect frameRect;
+
+ // Get image offsets with respect to the screen origin.
+ frameRect.SetRect(
+ LittleEndian::readUint16(aData + 0), LittleEndian::readUint16(aData + 2),
+ LittleEndian::readUint16(aData + 4), LittleEndian::readUint16(aData + 6));
+
+ if (!mGIFStruct.images_decoded) {
+ // Work around GIF files where
+ // * at least one of the logical screen dimensions is smaller than the
+ // same dimension in the first image, or
+ // * GIF87a files where the first image's dimensions do not match the
+ // logical screen dimensions.
+ if (mGIFStruct.screen_height < frameRect.Height() ||
+ mGIFStruct.screen_width < frameRect.Width() ||
+ mGIFStruct.version == 87) {
+ mGIFStruct.screen_height = frameRect.Height();
+ mGIFStruct.screen_width = frameRect.Width();
+ frameRect.MoveTo(0, 0);
+ }
+
+ // Create the image container with the right size.
+ BeginGIF();
+ if (HasError()) {
+ // Setting the size led to an error.
+ return Transition::TerminateFailure();
+ }
+
+ // If we're doing a metadata decode, we're done.
+ if (IsMetadataDecode()) {
+ CheckForTransparency(frameRect);
+ FinishInternal();
+ return Transition::TerminateSuccess();
+ }
+ }
+
+ // Work around broken GIF files that have zero frame width or height; in this
+ // case, we'll treat the frame as having the same size as the overall image.
+ if (frameRect.Height() == 0 || frameRect.Width() == 0) {
+ frameRect.SetHeight(mGIFStruct.screen_height);
+ frameRect.SetWidth(mGIFStruct.screen_width);
+
+ // If that still resulted in zero frame width or height, give up.
+ if (frameRect.Height() == 0 || frameRect.Width() == 0) {
+ return Transition::TerminateFailure();
+ }
+ }
+
+ // Determine |depth| (log base 2 of the number of colors in the palette).
+ bool haveLocalColorTable = false;
+ uint16_t depth = 0;
+ uint8_t packedFields = aData[8];
+
+ if (packedFields & PACKED_FIELDS_COLOR_TABLE_BIT) {
+ // Get the palette depth from the local color table.
+ depth = (packedFields & PACKED_FIELDS_TABLE_DEPTH_MASK) + 1;
+ haveLocalColorTable = true;
+ } else {
+ // Get the palette depth from the global color table.
+ depth = mGIFStruct.global_colormap_depth;
+ }
+
+ // If the transparent color index is greater than the number of colors in the
+ // color table, we may need a higher color depth than |depth| would specify.
+ // Our internal representation of the image will instead use |realDepth|,
+ // which is the smallest color depth that can accommodate the existing palette
+ // *and* the transparent color index.
+ uint16_t realDepth = depth;
+ while (mGIFStruct.tpixel >= (1 << realDepth) && realDepth < 8) {
+ realDepth++;
+ }
+
+ // Create a mask used to ensure that color values fit within the colormap.
+ mColorMask = 0xFF >> (8 - realDepth);
+
+ // Determine if this frame is interlaced or not.
+ const bool isInterlaced = packedFields & PACKED_FIELDS_INTERLACED_BIT;
+
+ // Create the SurfacePipe we'll use to write output for this frame.
+ if (NS_FAILED(BeginImageFrame(frameRect, realDepth, isInterlaced))) {
+ return Transition::TerminateFailure();
+ }
+
+ // Clear state from last image.
+ mGIFStruct.pixels_remaining =
+ int64_t(frameRect.Width()) * int64_t(frameRect.Height());
+
+ if (haveLocalColorTable) {
+ // We have a local color table, so prepare to read it into the palette of
+ // the current frame.
+ mGIFStruct.local_colormap_size = 1 << depth;
+
+ if (!mColormap) {
+ // Ensure our current colormap buffer is large enough to hold the new one.
+ mColormapSize = sizeof(uint32_t) << realDepth;
+ if (mGIFStruct.local_colormap_buffer_size < mColormapSize) {
+ if (mGIFStruct.local_colormap) {
+ free(mGIFStruct.local_colormap);
+ }
+ mGIFStruct.local_colormap_buffer_size = mColormapSize;
+ mGIFStruct.local_colormap =
+ static_cast<uint32_t*>(moz_xmalloc(mColormapSize));
+ // Ensure the local colormap is initialized as opaque.
+ memset(mGIFStruct.local_colormap, 0xFF, mColormapSize);
+ } else {
+ mColormapSize = mGIFStruct.local_colormap_buffer_size;
+ }
+
+ mColormap = mGIFStruct.local_colormap;
+ }
+
+ MOZ_ASSERT(mColormap);
+
+ const size_t size = 3 << depth;
+ if (mColormapSize > size) {
+ // Clear the part of the colormap which will be unused with this palette.
+ // If a GIF references an invalid palette entry, ensure the entry is
+ // opaque white. This is needed for Skia as if it isn't, RGBX surfaces
+ // will cause blending issues with Skia.
+ memset(reinterpret_cast<uint8_t*>(mColormap) + size, 0xFF,
+ mColormapSize - size);
+ }
+
+ MOZ_ASSERT(mColorTablePos == 0);
+
+ // We read the local color table in unbuffered mode since it can be quite
+ // large and it'd be preferable to avoid unnecessary copies.
+ return Transition::ToUnbuffered(State::FINISHED_LOCAL_COLOR_TABLE,
+ State::LOCAL_COLOR_TABLE, size);
+ }
+
+ // There's no local color table; copy the global color table into the palette
+ // of the current frame.
+ if (mColormap) {
+ memcpy(mColormap, mGIFStruct.global_colormap, mColormapSize);
+ } else {
+ mColormap = mGIFStruct.global_colormap;
+ }
+
+ return Transition::To(State::IMAGE_DATA_BLOCK, BLOCK_HEADER_LEN);
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadLocalColorTable(
+ const char* aData, size_t aLength) {
+ uint8_t* dest = reinterpret_cast<uint8_t*>(mColormap) + mColorTablePos;
+ memcpy(dest, aData, aLength);
+ mColorTablePos += aLength;
+ return Transition::ContinueUnbuffered(State::LOCAL_COLOR_TABLE);
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::FinishedLocalColorTable() {
+ ConvertColormap(mColormap, mGIFStruct.local_colormap_size);
+ mColorTablePos = 0;
+ return Transition::To(State::IMAGE_DATA_BLOCK, BLOCK_HEADER_LEN);
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadImageDataBlock(
+ const char* aData) {
+ // Make sure the transparent pixel is transparent in the colormap.
+ if (mGIFStruct.is_transparent) {
+ // Save the old value so we can restore it later.
+ if (mColormap == mGIFStruct.global_colormap) {
+ mOldColor = mColormap[mGIFStruct.tpixel];
+ }
+ mColormap[mGIFStruct.tpixel] = 0;
+ }
+
+ // Initialize the LZW decoder.
+ mGIFStruct.datasize = uint8_t(aData[0]);
+ if (mGIFStruct.datasize > MAX_LZW_BITS) {
+ return Transition::TerminateFailure();
+ }
+ const int clearCode = ClearCode();
+ if (clearCode >= MAX_BITS) {
+ return Transition::TerminateFailure();
+ }
+
+ mGIFStruct.avail = clearCode + 2;
+ mGIFStruct.oldcode = -1;
+ mGIFStruct.codesize = mGIFStruct.datasize + 1;
+ mGIFStruct.codemask = (1 << mGIFStruct.codesize) - 1;
+ mGIFStruct.datum = mGIFStruct.bits = 0;
+
+ // Initialize the tables.
+ for (int i = 0; i < clearCode; i++) {
+ mGIFStruct.suffix[i] = i;
+ }
+
+ mGIFStruct.stackp = mGIFStruct.stack;
+
+ // Begin reading image data sub-blocks.
+ return Transition::To(State::IMAGE_DATA_SUB_BLOCK, SUB_BLOCK_HEADER_LEN);
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadImageDataSubBlock(
+ const char* aData) {
+ const uint8_t subBlockLength = aData[0];
+ if (subBlockLength == 0) {
+ // We hit the block terminator.
+ EndImageFrame();
+ return Transition::To(State::BLOCK_HEADER, BLOCK_HEADER_LEN);
+ }
+
+ if (mGIFStruct.pixels_remaining == 0) {
+ // We've already written to the entire image; we should've hit the block
+ // terminator at this point. This image is corrupt, but we'll tolerate it.
+
+ if (subBlockLength == GIF_TRAILER) {
+ // This GIF is missing the block terminator for the final block; we'll put
+ // up with it.
+ FinishInternal();
+ return Transition::TerminateSuccess();
+ }
+
+ // We're not at the end of the image, so just skip the extra data.
+ return Transition::ToUnbuffered(State::FINISHED_LZW_DATA,
+ State::SKIP_LZW_DATA, subBlockLength);
+ }
+
+ // Handle the standard case: there's data in the sub-block and pixels left to
+ // fill in the image. We read the sub-block unbuffered so we can get pixels on
+ // the screen as soon as possible.
+ return Transition::ToUnbuffered(State::FINISHED_LZW_DATA, State::LZW_DATA,
+ subBlockLength);
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadLZWData(
+ const char* aData, size_t aLength) {
+ const uint8_t* data = reinterpret_cast<const uint8_t*>(aData);
+ size_t length = aLength;
+
+ while (mGIFStruct.pixels_remaining > 0 &&
+ (length > 0 || mGIFStruct.bits >= mGIFStruct.codesize)) {
+ size_t bytesRead = 0;
+
+ auto result = mPipe.WritePixelBlocks<uint32_t>(
+ [&](uint32_t* aPixelBlock, int32_t aBlockSize) {
+ return YieldPixels<uint32_t>(data, length, &bytesRead, aPixelBlock,
+ aBlockSize);
+ });
+
+ if (MOZ_UNLIKELY(bytesRead > length)) {
+ MOZ_ASSERT_UNREACHABLE("Overread?");
+ bytesRead = length;
+ }
+
+ // Advance our position in the input based upon what YieldPixel() consumed.
+ data += bytesRead;
+ length -= bytesRead;
+
+ switch (result) {
+ case WriteState::NEED_MORE_DATA:
+ continue;
+
+ case WriteState::FINISHED:
+ NS_WARNING_ASSERTION(mGIFStruct.pixels_remaining <= 0,
+ "too many pixels");
+ mGIFStruct.pixels_remaining = 0;
+ break;
+
+ case WriteState::FAILURE:
+ return Transition::TerminateFailure();
+ }
+ }
+
+ // We're done, but keep going until we consume all the data in the sub-block.
+ return Transition::ContinueUnbuffered(State::LZW_DATA);
+}
+
+LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::SkipSubBlocks(
+ const char* aData) {
+ // In the SKIP_SUB_BLOCKS state we skip over data sub-blocks that we're not
+ // interested in. Blocks consist of a block header (which can be up to 255
+ // bytes in length) and a series of data sub-blocks. Each data sub-block
+ // consists of a single byte length value, followed by the data itself. A data
+ // sub-block with a length of zero terminates the overall block.
+ // SKIP_SUB_BLOCKS reads a sub-block length value. If it's zero, we've arrived
+ // at the next block. Otherwise, we enter the SKIP_DATA_THEN_SKIP_SUB_BLOCKS
+ // state to skip over the sub-block data and return to SKIP_SUB_BLOCKS at the
+ // start of the next sub-block.
+
+ const uint8_t nextSubBlockLength = aData[0];
+ if (nextSubBlockLength == 0) {
+ // We hit the block terminator, so the sequence of data sub-blocks is over;
+ // begin processing another block.
+ return Transition::To(State::BLOCK_HEADER, BLOCK_HEADER_LEN);
+ }
+
+ // Skip to the next sub-block length value.
+ return Transition::ToUnbuffered(State::FINISHED_SKIPPING_DATA,
+ State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS,
+ nextSubBlockLength);
+}
+
+Maybe<Telemetry::HistogramID> nsGIFDecoder2::SpeedHistogram() const {
+ return Some(Telemetry::IMAGE_DECODE_SPEED_GIF);
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/decoders/nsGIFDecoder2.h b/image/decoders/nsGIFDecoder2.h
new file mode 100644
index 0000000000..5a6c501778
--- /dev/null
+++ b/image/decoders/nsGIFDecoder2.h
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_nsGIFDecoder2_h
+#define mozilla_image_decoders_nsGIFDecoder2_h
+
+#include "Decoder.h"
+#include "GIF2.h"
+#include "StreamingLexer.h"
+#include "SurfacePipe.h"
+#include "mozilla/gfx/Swizzle.h"
+
+namespace mozilla {
+namespace image {
+class RasterImage;
+
+//////////////////////////////////////////////////////////////////////
+// nsGIFDecoder2 Definition
+
+class nsGIFDecoder2 : public Decoder {
+ public:
+ ~nsGIFDecoder2();
+
+ DecoderType GetType() const override { return DecoderType::GIF; }
+
+ protected:
+ LexerResult DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) override;
+ nsresult FinishInternal() override;
+
+ Maybe<Telemetry::HistogramID> SpeedHistogram() const override;
+
+ private:
+ friend class DecoderFactory;
+
+ // Decoders should only be instantiated via DecoderFactory.
+ explicit nsGIFDecoder2(RasterImage* aImage);
+
+ /// Called when we begin decoding the image.
+ void BeginGIF();
+
+ /**
+ * Called when we begin decoding a frame.
+ *
+ * @param aFrameRect The region of the image that contains data. The region
+ * outside this rect is transparent.
+ * @param aDepth The palette depth of this frame.
+ * @param aIsInterlaced If true, this frame is an interlaced frame.
+ */
+ nsresult BeginImageFrame(const OrientedIntRect& aFrameRect, uint16_t aDepth,
+ bool aIsInterlaced);
+
+ /// Called when we finish decoding a frame.
+ void EndImageFrame();
+
+ /// Called when we finish decoding the entire image.
+ void FlushImageData();
+
+ /// Convert color map to BGRA, applying any necessary CMS transforms.
+ void ConvertColormap(uint32_t* aColormap, uint32_t aColors);
+
+ /// Transforms a palette index into a pixel.
+ template <typename PixelSize>
+ PixelSize ColormapIndexToPixel(uint8_t aIndex);
+
+ /// A generator function that performs LZW decompression and yields pixels.
+ template <typename PixelSize>
+ std::tuple<int32_t, Maybe<WriteState>> YieldPixels(const uint8_t* aData,
+ size_t aLength,
+ size_t* aBytesReadOut,
+ PixelSize* aPixelBlock,
+ int32_t aBlockSize);
+
+ /// Checks if we have transparency, either because the header indicates that
+ /// there's alpha, or because the frame rect doesn't cover the entire image.
+ bool CheckForTransparency(const OrientedIntRect& aFrameRect);
+
+ // @return the clear code used for LZW decompression.
+ int ClearCode() const {
+ MOZ_ASSERT(mGIFStruct.datasize <= MAX_LZW_BITS);
+ return 1 << mGIFStruct.datasize;
+ }
+
+ enum class State {
+ FAILURE,
+ SUCCESS,
+ GIF_HEADER,
+ SCREEN_DESCRIPTOR,
+ GLOBAL_COLOR_TABLE,
+ FINISHED_GLOBAL_COLOR_TABLE,
+ BLOCK_HEADER,
+ EXTENSION_HEADER,
+ GRAPHIC_CONTROL_EXTENSION,
+ APPLICATION_IDENTIFIER,
+ NETSCAPE_EXTENSION_SUB_BLOCK,
+ NETSCAPE_EXTENSION_DATA,
+ IMAGE_DESCRIPTOR,
+ FINISH_IMAGE_DESCRIPTOR,
+ LOCAL_COLOR_TABLE,
+ FINISHED_LOCAL_COLOR_TABLE,
+ IMAGE_DATA_BLOCK,
+ IMAGE_DATA_SUB_BLOCK,
+ LZW_DATA,
+ SKIP_LZW_DATA,
+ FINISHED_LZW_DATA,
+ SKIP_SUB_BLOCKS,
+ SKIP_DATA_THEN_SKIP_SUB_BLOCKS,
+ FINISHED_SKIPPING_DATA
+ };
+
+ LexerTransition<State> ReadGIFHeader(const char* aData);
+ LexerTransition<State> ReadScreenDescriptor(const char* aData);
+ LexerTransition<State> ReadGlobalColorTable(const char* aData,
+ size_t aLength);
+ LexerTransition<State> FinishedGlobalColorTable();
+ LexerTransition<State> ReadBlockHeader(const char* aData);
+ LexerTransition<State> ReadExtensionHeader(const char* aData);
+ LexerTransition<State> ReadGraphicControlExtension(const char* aData);
+ LexerTransition<State> ReadApplicationIdentifier(const char* aData);
+ LexerTransition<State> ReadNetscapeExtensionSubBlock(const char* aData);
+ LexerTransition<State> ReadNetscapeExtensionData(const char* aData);
+ LexerTransition<State> ReadImageDescriptor(const char* aData);
+ LexerTransition<State> FinishImageDescriptor(const char* aData);
+ LexerTransition<State> ReadLocalColorTable(const char* aData, size_t aLength);
+ LexerTransition<State> FinishedLocalColorTable();
+ LexerTransition<State> ReadImageDataBlock(const char* aData);
+ LexerTransition<State> ReadImageDataSubBlock(const char* aData);
+ LexerTransition<State> ReadLZWData(const char* aData, size_t aLength);
+ LexerTransition<State> SkipSubBlocks(const char* aData);
+
+ // The StreamingLexer used to manage input. The initial size of the buffer is
+ // chosen as a little larger than the maximum size of any fixed-length data we
+ // have to read for a state. We read variable-length data in unbuffered mode
+ // so the buffer shouldn't have to be resized during decoding.
+ StreamingLexer<State, 16> mLexer;
+
+ uint32_t mOldColor; // The old value of the transparent pixel
+
+ // The frame number of the currently-decoding frame when we're in the middle
+ // of decoding it, and -1 otherwise.
+ int32_t mCurrentFrameIndex;
+
+ // When we're reading in the global or local color table, this records our
+ // current position - i.e., the offset into which the next byte should be
+ // written.
+ size_t mColorTablePos;
+ uint32_t* mColormap; // Current colormap to be used in Cairo format
+ uint32_t mColormapSize;
+
+ uint8_t mColorMask; // Apply this to the pixel to keep within colormap
+ bool mGIFOpen;
+ bool mSawTransparency;
+
+ gif_struct mGIFStruct;
+
+ gfx::SwizzleRowFn mSwizzleFn; /// Method to unpack color tables from RGB.
+ SurfacePipe mPipe; /// The SurfacePipe used to write to the output surface.
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_decoders_nsGIFDecoder2_h
diff --git a/image/decoders/nsICODecoder.cpp b/image/decoders/nsICODecoder.cpp
new file mode 100644
index 0000000000..ff37355429
--- /dev/null
+++ b/image/decoders/nsICODecoder.cpp
@@ -0,0 +1,709 @@
+/* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* This is a Cross-Platform ICO Decoder, which should work everywhere, including
+ * Big-Endian machines like the PowerPC. */
+
+#include "nsICODecoder.h"
+
+#include <stdlib.h>
+
+#include <utility>
+
+#include "RasterImage.h"
+#include "mozilla/EndianUtils.h"
+#include "mozilla/gfx/Swizzle.h"
+#include "mozilla/UniquePtrExtensions.h"
+
+using namespace mozilla::gfx;
+
+namespace mozilla {
+namespace image {
+
+// Constants.
+static const uint32_t ICOHEADERSIZE = 6;
+static const uint32_t BITMAPINFOSIZE = bmp::InfoHeaderLength::WIN_ICO;
+
+// ----------------------------------------
+// Actual Data Processing
+// ----------------------------------------
+
+// Obtains the number of colors from the bits per pixel
+uint16_t nsICODecoder::GetNumColors() {
+ uint16_t numColors = 0;
+ if (mBPP <= 8) {
+ switch (mBPP) {
+ case 1:
+ numColors = 2;
+ break;
+ case 4:
+ numColors = 16;
+ break;
+ case 8:
+ numColors = 256;
+ break;
+ default:
+ numColors = (uint16_t)-1;
+ }
+ }
+ return numColors;
+}
+
+nsICODecoder::nsICODecoder(RasterImage* aImage)
+ : Decoder(aImage),
+ mLexer(Transition::To(ICOState::HEADER, ICOHEADERSIZE),
+ Transition::TerminateSuccess()),
+ mDirEntry(nullptr),
+ mNumIcons(0),
+ mCurrIcon(0),
+ mBPP(0),
+ mMaskRowSize(0),
+ mCurrMaskLine(0),
+ mIsCursor(false),
+ mHasMaskAlpha(false) {}
+
+nsresult nsICODecoder::FinishInternal() {
+ // We shouldn't be called in error cases
+ MOZ_ASSERT(!HasError(), "Shouldn't call FinishInternal after error!");
+
+ return GetFinalStateFromContainedDecoder();
+}
+
+nsresult nsICODecoder::FinishWithErrorInternal() {
+ // No need to assert !mInFrame here because this condition is enforced by
+ // mContainedDecoder.
+ return GetFinalStateFromContainedDecoder();
+}
+
+nsresult nsICODecoder::GetFinalStateFromContainedDecoder() {
+ if (!mContainedDecoder) {
+ return NS_OK;
+ }
+
+ // Let the contained decoder finish up if necessary.
+ FlushContainedDecoder();
+
+ // Make our state the same as the state of the contained decoder.
+ mDecodeDone = mContainedDecoder->GetDecodeDone();
+ mProgress |= mContainedDecoder->TakeProgress();
+ mInvalidRect.UnionRect(mInvalidRect, mContainedDecoder->TakeInvalidRect());
+ mCurrentFrame = mContainedDecoder->GetCurrentFrameRef();
+
+ // Finalize the frame which we deferred to ensure we could modify the final
+ // result (e.g. to apply the BMP mask).
+ MOZ_ASSERT(!mContainedDecoder->GetFinalizeFrames());
+ if (mCurrentFrame) {
+ mCurrentFrame->FinalizeSurface();
+ }
+
+ // Propagate errors.
+ nsresult rv =
+ HasError() || mContainedDecoder->HasError() ? NS_ERROR_FAILURE : NS_OK;
+
+ MOZ_ASSERT(NS_FAILED(rv) || !mCurrentFrame || mCurrentFrame->IsFinished());
+ return rv;
+}
+
+LexerTransition<ICOState> nsICODecoder::ReadHeader(const char* aData) {
+ // If the third byte is 1, this is an icon. If 2, a cursor.
+ if ((aData[2] != 1) && (aData[2] != 2)) {
+ return Transition::TerminateFailure();
+ }
+ mIsCursor = (aData[2] == 2);
+
+ // The fifth and sixth bytes specify the number of resources in the file.
+ mNumIcons = LittleEndian::readUint16(aData + 4);
+ if (mNumIcons == 0) {
+ return Transition::TerminateSuccess(); // Nothing to do.
+ }
+
+ // Downscale-during-decode can end up decoding different resources in the ICO
+ // file depending on the target size. Since the resources are not necessarily
+ // scaled versions of the same image, some may be transparent and some may not
+ // be. We could be precise about transparency if we decoded the metadata of
+ // every resource, but for now we don't and it's safest to assume that
+ // transparency could be present.
+ PostHasTransparency();
+
+ return Transition::To(ICOState::DIR_ENTRY, ICODIRENTRYSIZE);
+}
+
+size_t nsICODecoder::FirstResourceOffset() const {
+ MOZ_ASSERT(mNumIcons > 0,
+ "Calling FirstResourceOffset before processing header");
+
+ // The first resource starts right after the directory, which starts right
+ // after the ICO header.
+ return ICOHEADERSIZE + mNumIcons * ICODIRENTRYSIZE;
+}
+
+LexerTransition<ICOState> nsICODecoder::ReadDirEntry(const char* aData) {
+ mCurrIcon++;
+
+ // Ensure the resource has an offset past the ICO headers.
+ uint32_t offset = LittleEndian::readUint32(aData + 12);
+ if (offset >= FirstResourceOffset()) {
+ // Read the directory entry.
+ IconDirEntryEx e;
+ e.mWidth = aData[0];
+ e.mHeight = aData[1];
+ e.mColorCount = aData[2];
+ e.mReserved = aData[3];
+ e.mPlanes = LittleEndian::readUint16(aData + 4);
+ e.mBitCount = LittleEndian::readUint16(aData + 6);
+ e.mBytesInRes = LittleEndian::readUint32(aData + 8);
+ e.mImageOffset = offset;
+ e.mSize = OrientedIntSize(e.mWidth, e.mHeight);
+
+ // Only accept entries with sufficient resource data to actually contain
+ // some image data.
+ if (e.mBytesInRes > BITMAPINFOSIZE) {
+ if (e.mWidth == 0 || e.mHeight == 0) {
+ mUnsizedDirEntries.AppendElement(e);
+ } else {
+ mDirEntries.AppendElement(e);
+ }
+ }
+ }
+
+ if (mCurrIcon == mNumIcons) {
+ if (mUnsizedDirEntries.IsEmpty()) {
+ return Transition::To(ICOState::FINISHED_DIR_ENTRY, 0);
+ }
+ return Transition::To(ICOState::ITERATE_UNSIZED_DIR_ENTRY, 0);
+ }
+
+ return Transition::To(ICOState::DIR_ENTRY, ICODIRENTRYSIZE);
+}
+
+LexerTransition<ICOState> nsICODecoder::IterateUnsizedDirEntry() {
+ MOZ_ASSERT(!mUnsizedDirEntries.IsEmpty());
+
+ if (!mDirEntry) {
+ // The first time we are here, there is no entry selected. We must prepare a
+ // new iterator for the contained decoder to advance as it wills. Cloning at
+ // this point ensures it will begin at the end of the dir entries.
+ mReturnIterator = mLexer.Clone(*mIterator, SIZE_MAX);
+ if (mReturnIterator.isNothing()) {
+ // If we cannot read further than this point, then there is no resource
+ // data to read.
+ return Transition::TerminateFailure();
+ }
+ } else {
+ // We have already selected an entry which means a metadata decoder has
+ // finished. Verify the size is valid and if so, add to the discovered
+ // resources.
+ if (mDirEntry->mSize.width > 0 && mDirEntry->mSize.height > 0) {
+ mDirEntries.AppendElement(*mDirEntry);
+ }
+
+ // Remove the entry from the unsized list either way.
+ mDirEntry = nullptr;
+ mUnsizedDirEntries.RemoveElementAt(0);
+
+ // Our iterator is at an unknown point, so reset it to the point that we
+ // saved.
+ mIterator = mLexer.Clone(*mReturnIterator, SIZE_MAX);
+ if (mIterator.isNothing()) {
+ MOZ_ASSERT_UNREACHABLE("Cannot re-clone return iterator");
+ return Transition::TerminateFailure();
+ }
+ }
+
+ // There are no more unsized entries, so we can finally decide which entry to
+ // select for decoding.
+ if (mUnsizedDirEntries.IsEmpty()) {
+ mReturnIterator.reset();
+ return Transition::To(ICOState::FINISHED_DIR_ENTRY, 0);
+ }
+
+ // Move to the resource data to start metadata decoding.
+ mDirEntry = &mUnsizedDirEntries[0];
+ size_t offsetToResource = mDirEntry->mImageOffset - FirstResourceOffset();
+ return Transition::ToUnbuffered(ICOState::FOUND_RESOURCE,
+ ICOState::SKIP_TO_RESOURCE, offsetToResource);
+}
+
+LexerTransition<ICOState> nsICODecoder::FinishDirEntry() {
+ MOZ_ASSERT(!mDirEntry);
+
+ if (mDirEntries.IsEmpty()) {
+ return Transition::TerminateFailure();
+ }
+
+ // If an explicit output size was specified, we'll try to select the resource
+ // that matches it best below.
+ const Maybe<OrientedIntSize> desiredSize = ExplicitOutputSize();
+
+ // Determine the biggest resource. We always use the biggest resource for the
+ // intrinsic size, and if we don't have a specific desired size, we select it
+ // as the best resource as well.
+ int32_t bestDelta = INT32_MIN;
+ IconDirEntryEx* biggestEntry = nullptr;
+
+ for (size_t i = 0; i < mDirEntries.Length(); ++i) {
+ IconDirEntryEx& e = mDirEntries[i];
+ mImageMetadata.AddNativeSize(e.mSize);
+
+ if (!biggestEntry ||
+ (e.mBitCount >= biggestEntry->mBitCount &&
+ e.mSize.width * e.mSize.height >=
+ biggestEntry->mSize.width * biggestEntry->mSize.height)) {
+ biggestEntry = &e;
+
+ if (!desiredSize) {
+ mDirEntry = &e;
+ }
+ }
+
+ if (desiredSize) {
+ // Calculate the delta between this resource's size and the desired size,
+ // so we can see if it is better than our current-best option. In the
+ // case of several equally-good resources, we use the last one. "Better"
+ // in this case is determined by |delta|, a measure of the difference in
+ // size between the entry we've found and the desired size. We will choose
+ // the smallest resource that is greater than or equal to the desired size
+ // (i.e. we assume it's better to downscale a larger icon than to upscale
+ // a smaller one).
+ int32_t delta = std::min(e.mSize.width - desiredSize->width,
+ e.mSize.height - desiredSize->height);
+ if (!mDirEntry || (e.mBitCount >= mDirEntry->mBitCount &&
+ ((bestDelta < 0 && delta >= bestDelta) ||
+ (delta >= 0 && delta <= bestDelta)))) {
+ mDirEntry = &e;
+ bestDelta = delta;
+ }
+ }
+ }
+
+ MOZ_ASSERT(mDirEntry);
+ MOZ_ASSERT(biggestEntry);
+
+ // If this is a cursor, set the hotspot. We use the hotspot from the biggest
+ // resource since we also use that resource for the intrinsic size.
+ if (mIsCursor) {
+ mImageMetadata.SetHotspot(biggestEntry->mXHotspot, biggestEntry->mYHotspot);
+ }
+
+ // We always report the biggest resource's size as the intrinsic size; this
+ // is necessary for downscale-during-decode to work since we won't even
+ // attempt to *upscale* while decoding.
+ PostSize(biggestEntry->mSize.width, biggestEntry->mSize.height);
+ if (HasError()) {
+ return Transition::TerminateFailure();
+ }
+
+ if (IsMetadataDecode()) {
+ return Transition::TerminateSuccess();
+ }
+
+ if (mDirEntry->mSize == OutputSize()) {
+ // If the resource we selected matches the output size perfectly, we don't
+ // need to do any downscaling.
+ MOZ_ASSERT_IF(desiredSize, mDirEntry->mSize == *desiredSize);
+ MOZ_ASSERT_IF(!desiredSize, mDirEntry->mSize == Size());
+ } else if (OutputSize().width < mDirEntry->mSize.width ||
+ OutputSize().height < mDirEntry->mSize.height) {
+ // Create a downscaler if we need to downscale.
+ //
+ // TODO(aosmond): This is the last user of Downscaler. We should switch this
+ // to SurfacePipe as well so we can remove the code from tree.
+ mDownscaler.emplace(OutputSize().ToUnknownSize());
+ }
+
+ size_t offsetToResource = mDirEntry->mImageOffset - FirstResourceOffset();
+ return Transition::ToUnbuffered(ICOState::FOUND_RESOURCE,
+ ICOState::SKIP_TO_RESOURCE, offsetToResource);
+}
+
+LexerTransition<ICOState> nsICODecoder::SniffResource(const char* aData) {
+ MOZ_ASSERT(mDirEntry);
+
+ // We have BITMAPINFOSIZE bytes buffered at this point. We know an embedded
+ // BMP will have at least that many bytes by definition. We can also infer
+ // that any valid embedded PNG will contain that many bytes as well because:
+ // BITMAPINFOSIZE
+ // <
+ // signature (8 bytes) +
+ // IHDR (12 bytes header + 13 bytes data)
+ // IDAT (12 bytes header)
+
+ // We use the first PNGSIGNATURESIZE bytes to determine whether this resource
+ // is a PNG or a BMP.
+ bool isPNG =
+ !memcmp(aData, nsPNGDecoder::pngSignatureBytes, PNGSIGNATURESIZE);
+ if (isPNG) {
+ if (mDirEntry->mBytesInRes <= BITMAPINFOSIZE) {
+ return Transition::TerminateFailure();
+ }
+
+ // Prepare a new iterator for the contained decoder to advance as it wills.
+ // Cloning at the point ensures it will begin at the resource offset.
+ Maybe<SourceBufferIterator> containedIterator =
+ mLexer.Clone(*mIterator, mDirEntry->mBytesInRes);
+ if (containedIterator.isNothing()) {
+ return Transition::TerminateFailure();
+ }
+
+ // Create a PNG decoder which will do the rest of the work for us.
+ bool metadataDecode = mReturnIterator.isSome();
+ Maybe<OrientedIntSize> expectedSize =
+ metadataDecode ? Nothing() : Some(mDirEntry->mSize);
+ mContainedDecoder = DecoderFactory::CreateDecoderForICOResource(
+ DecoderType::PNG, std::move(containedIterator.ref()), WrapNotNull(this),
+ metadataDecode, expectedSize);
+
+ // Read in the rest of the PNG unbuffered.
+ size_t toRead = mDirEntry->mBytesInRes - BITMAPINFOSIZE;
+ return Transition::ToUnbuffered(ICOState::FINISHED_RESOURCE,
+ ICOState::READ_RESOURCE, toRead);
+ }
+
+ // Make sure we have a sane size for the bitmap information header.
+ int32_t bihSize = LittleEndian::readUint32(aData);
+ if (bihSize != static_cast<int32_t>(BITMAPINFOSIZE)) {
+ return Transition::TerminateFailure();
+ }
+
+ // Read in the rest of the bitmap information header.
+ return ReadBIH(aData);
+}
+
+LexerTransition<ICOState> nsICODecoder::ReadResource() {
+ if (!FlushContainedDecoder()) {
+ return Transition::TerminateFailure();
+ }
+
+ return Transition::ContinueUnbuffered(ICOState::READ_RESOURCE);
+}
+
+LexerTransition<ICOState> nsICODecoder::ReadBIH(const char* aData) {
+ MOZ_ASSERT(mDirEntry);
+
+ // Extract the BPP from the BIH header; it should be trusted over the one
+ // we have from the ICO header which is usually set to 0.
+ mBPP = LittleEndian::readUint16(aData + 14);
+
+ // Check to make sure we have valid color settings.
+ uint16_t numColors = GetNumColors();
+ if (numColors == uint16_t(-1)) {
+ return Transition::TerminateFailure();
+ }
+
+ // The color table is present only if BPP is <= 8.
+ MOZ_ASSERT_IF(mBPP > 8, numColors == 0);
+
+ // The ICO format when containing a BMP does not include the 14 byte
+ // bitmap file header. So we create the BMP decoder via the constructor that
+ // tells it to skip this, and pass in the required data (dataOffset) that
+ // would have been present in the header.
+ uint32_t dataOffset =
+ bmp::FILE_HEADER_LENGTH + BITMAPINFOSIZE + 4 * numColors;
+
+ // Prepare a new iterator for the contained decoder to advance as it wills.
+ // Cloning at the point ensures it will begin at the resource offset.
+ Maybe<SourceBufferIterator> containedIterator =
+ mLexer.Clone(*mIterator, mDirEntry->mBytesInRes);
+ if (containedIterator.isNothing()) {
+ return Transition::TerminateFailure();
+ }
+
+ // Create a BMP decoder which will do most of the work for us; the exception
+ // is the AND mask, which isn't present in standalone BMPs.
+ bool metadataDecode = mReturnIterator.isSome();
+ Maybe<OrientedIntSize> expectedSize =
+ metadataDecode ? Nothing() : Some(mDirEntry->mSize);
+ mContainedDecoder = DecoderFactory::CreateDecoderForICOResource(
+ DecoderType::BMP, std::move(containedIterator.ref()), WrapNotNull(this),
+ metadataDecode, expectedSize, Some(dataOffset));
+
+ RefPtr<nsBMPDecoder> bmpDecoder =
+ static_cast<nsBMPDecoder*>(mContainedDecoder.get());
+
+ // Ensure the decoder has parsed at least the BMP's bitmap info header.
+ if (!FlushContainedDecoder()) {
+ return Transition::TerminateFailure();
+ }
+
+ // If this is a metadata decode, FinishResource will any necessary checks.
+ if (mContainedDecoder->IsMetadataDecode()) {
+ return Transition::To(ICOState::FINISHED_RESOURCE, 0);
+ }
+
+ // Do we have an AND mask on this BMP? If so, we need to read it after we read
+ // the BMP data itself.
+ uint32_t bmpDataLength = bmpDecoder->GetCompressedImageSize() + 4 * numColors;
+ bool hasANDMask = (BITMAPINFOSIZE + bmpDataLength) < mDirEntry->mBytesInRes;
+ ICOState afterBMPState =
+ hasANDMask ? ICOState::PREPARE_FOR_MASK : ICOState::FINISHED_RESOURCE;
+
+ // Read in the rest of the BMP unbuffered.
+ return Transition::ToUnbuffered(afterBMPState, ICOState::READ_RESOURCE,
+ bmpDataLength);
+}
+
+LexerTransition<ICOState> nsICODecoder::PrepareForMask() {
+ MOZ_ASSERT(mDirEntry);
+ MOZ_ASSERT(mContainedDecoder->GetDecodeDone());
+
+ // We have received all of the data required by the BMP decoder so flushing
+ // here guarantees the decode has finished.
+ if (!FlushContainedDecoder()) {
+ return Transition::TerminateFailure();
+ }
+
+ MOZ_ASSERT(mContainedDecoder->GetDecodeDone());
+
+ RefPtr<nsBMPDecoder> bmpDecoder =
+ static_cast<nsBMPDecoder*>(mContainedDecoder.get());
+
+ uint16_t numColors = GetNumColors();
+ MOZ_ASSERT(numColors != uint16_t(-1));
+
+ // Determine the length of the AND mask.
+ uint32_t bmpLengthWithHeader =
+ BITMAPINFOSIZE + bmpDecoder->GetCompressedImageSize() + 4 * numColors;
+ MOZ_ASSERT(bmpLengthWithHeader < mDirEntry->mBytesInRes);
+ uint32_t maskLength = mDirEntry->mBytesInRes - bmpLengthWithHeader;
+
+ // If the BMP provides its own transparency, we ignore the AND mask.
+ if (bmpDecoder->HasTransparency()) {
+ return Transition::ToUnbuffered(ICOState::FINISHED_RESOURCE,
+ ICOState::SKIP_MASK, maskLength);
+ }
+
+ // Compute the row size for the mask.
+ mMaskRowSize = ((mDirEntry->mSize.width + 31) / 32) * 4; // + 31 to round up
+
+ // If the expected size of the AND mask is larger than its actual size, then
+ // we must have a truncated (and therefore corrupt) AND mask.
+ uint32_t expectedLength = mMaskRowSize * mDirEntry->mSize.height;
+ if (maskLength < expectedLength) {
+ return Transition::TerminateFailure();
+ }
+
+ // If we're downscaling, the mask is the wrong size for the surface we've
+ // produced, so we need to downscale the mask into a temporary buffer and then
+ // combine the mask's alpha values with the color values from the image.
+ if (mDownscaler) {
+ MOZ_ASSERT(bmpDecoder->GetImageDataLength() ==
+ mDownscaler->TargetSize().width *
+ mDownscaler->TargetSize().height * sizeof(uint32_t));
+ mMaskBuffer =
+ MakeUniqueFallible<uint8_t[]>(bmpDecoder->GetImageDataLength());
+ if (NS_WARN_IF(!mMaskBuffer)) {
+ return Transition::TerminateFailure();
+ }
+ nsresult rv = mDownscaler->BeginFrame(mDirEntry->mSize.ToUnknownSize(),
+ Nothing(), mMaskBuffer.get(),
+ /* aHasAlpha = */ true,
+ /* aFlipVertically = */ true);
+ if (NS_FAILED(rv)) {
+ return Transition::TerminateFailure();
+ }
+ }
+
+ mCurrMaskLine = mDirEntry->mSize.height;
+ return Transition::To(ICOState::READ_MASK_ROW, mMaskRowSize);
+}
+
+LexerTransition<ICOState> nsICODecoder::ReadMaskRow(const char* aData) {
+ MOZ_ASSERT(mDirEntry);
+
+ mCurrMaskLine--;
+
+ uint8_t sawTransparency = 0;
+
+ // Get the mask row we're reading.
+ const uint8_t* mask = reinterpret_cast<const uint8_t*>(aData);
+ const uint8_t* maskRowEnd = mask + mMaskRowSize;
+
+ // Get the corresponding row of the mask buffer (if we're downscaling) or the
+ // decoded image data (if we're not).
+ uint32_t* decoded = nullptr;
+ if (mDownscaler) {
+ // Initialize the row to all white and fully opaque.
+ memset(mDownscaler->RowBuffer(), 0xFF,
+ mDirEntry->mSize.width * sizeof(uint32_t));
+
+ decoded = reinterpret_cast<uint32_t*>(mDownscaler->RowBuffer());
+ } else {
+ RefPtr<nsBMPDecoder> bmpDecoder =
+ static_cast<nsBMPDecoder*>(mContainedDecoder.get());
+ uint32_t* imageData = bmpDecoder->GetImageData();
+ if (!imageData) {
+ return Transition::TerminateFailure();
+ }
+
+ decoded = imageData + mCurrMaskLine * mDirEntry->mSize.width;
+ }
+
+ MOZ_ASSERT(decoded);
+ uint32_t* decodedRowEnd = decoded + mDirEntry->mSize.width;
+
+ // Iterate simultaneously through the AND mask and the image data.
+ while (mask < maskRowEnd) {
+ uint8_t idx = *mask++;
+ sawTransparency |= idx;
+ for (uint8_t bit = 0x80; bit && decoded < decodedRowEnd; bit >>= 1) {
+ // Clear pixel completely for transparency.
+ if (idx & bit) {
+ *decoded = 0;
+ }
+ decoded++;
+ }
+ }
+
+ if (mDownscaler) {
+ mDownscaler->CommitRow();
+ }
+
+ // If any bits are set in sawTransparency, then we know at least one pixel was
+ // transparent.
+ if (sawTransparency) {
+ mHasMaskAlpha = true;
+ }
+
+ if (mCurrMaskLine == 0) {
+ return Transition::To(ICOState::FINISH_MASK, 0);
+ }
+
+ return Transition::To(ICOState::READ_MASK_ROW, mMaskRowSize);
+}
+
+LexerTransition<ICOState> nsICODecoder::FinishMask() {
+ // If we're downscaling, we now have the appropriate alpha values in
+ // mMaskBuffer. We just need to transfer them to the image.
+ if (mDownscaler) {
+ // Retrieve the image data.
+ RefPtr<nsBMPDecoder> bmpDecoder =
+ static_cast<nsBMPDecoder*>(mContainedDecoder.get());
+ uint8_t* imageData = reinterpret_cast<uint8_t*>(bmpDecoder->GetImageData());
+ if (!imageData) {
+ return Transition::TerminateFailure();
+ }
+
+ // Iterate through the alpha values, copying from mask to image.
+ MOZ_ASSERT(mMaskBuffer);
+ MOZ_ASSERT(bmpDecoder->GetImageDataLength() > 0);
+ for (size_t i = 3; i < bmpDecoder->GetImageDataLength(); i += 4) {
+ imageData[i] = mMaskBuffer[i];
+ }
+ int32_t stride = mDownscaler->TargetSize().width * sizeof(uint32_t);
+ DebugOnly<bool> ret =
+ // We know the format is OS_RGBA because we always assume bmp's inside
+ // ico's are transparent.
+ PremultiplyData(imageData, stride, SurfaceFormat::OS_RGBA, imageData,
+ stride, SurfaceFormat::OS_RGBA,
+ mDownscaler->TargetSize());
+ MOZ_ASSERT(ret);
+ }
+
+ return Transition::To(ICOState::FINISHED_RESOURCE, 0);
+}
+
+LexerTransition<ICOState> nsICODecoder::FinishResource() {
+ MOZ_ASSERT(mDirEntry);
+
+ // We have received all of the data required by the PNG/BMP decoder so
+ // flushing here guarantees the decode has finished.
+ if (!FlushContainedDecoder()) {
+ return Transition::TerminateFailure();
+ }
+
+ MOZ_ASSERT(mContainedDecoder->GetDecodeDone());
+
+ // If it is a metadata decode, all we were trying to get was the size
+ // information missing from the dir entry.
+ if (mContainedDecoder->IsMetadataDecode()) {
+ if (mContainedDecoder->HasSize()) {
+ mDirEntry->mSize = mContainedDecoder->Size();
+ }
+ return Transition::To(ICOState::ITERATE_UNSIZED_DIR_ENTRY, 0);
+ }
+
+ // Raymond Chen says that 32bpp only are valid PNG ICOs
+ // http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx
+ if (!mContainedDecoder->IsValidICOResource()) {
+ return Transition::TerminateFailure();
+ }
+
+ // This size from the resource should match that from the dir entry.
+ MOZ_ASSERT_IF(mContainedDecoder->HasSize(),
+ mContainedDecoder->Size() == mDirEntry->mSize);
+
+ return Transition::TerminateSuccess();
+}
+
+LexerResult nsICODecoder::DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) {
+ MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
+
+ return mLexer.Lex(
+ aIterator, aOnResume,
+ [=](ICOState aState, const char* aData, size_t aLength) {
+ switch (aState) {
+ case ICOState::HEADER:
+ return ReadHeader(aData);
+ case ICOState::DIR_ENTRY:
+ return ReadDirEntry(aData);
+ case ICOState::FINISHED_DIR_ENTRY:
+ return FinishDirEntry();
+ case ICOState::ITERATE_UNSIZED_DIR_ENTRY:
+ return IterateUnsizedDirEntry();
+ case ICOState::SKIP_TO_RESOURCE:
+ return Transition::ContinueUnbuffered(ICOState::SKIP_TO_RESOURCE);
+ case ICOState::FOUND_RESOURCE:
+ return Transition::To(ICOState::SNIFF_RESOURCE, BITMAPINFOSIZE);
+ case ICOState::SNIFF_RESOURCE:
+ return SniffResource(aData);
+ case ICOState::READ_RESOURCE:
+ return ReadResource();
+ case ICOState::PREPARE_FOR_MASK:
+ return PrepareForMask();
+ case ICOState::READ_MASK_ROW:
+ return ReadMaskRow(aData);
+ case ICOState::FINISH_MASK:
+ return FinishMask();
+ case ICOState::SKIP_MASK:
+ return Transition::ContinueUnbuffered(ICOState::SKIP_MASK);
+ case ICOState::FINISHED_RESOURCE:
+ return FinishResource();
+ default:
+ MOZ_CRASH("Unknown ICOState");
+ }
+ });
+}
+
+bool nsICODecoder::FlushContainedDecoder() {
+ MOZ_ASSERT(mContainedDecoder);
+
+ bool succeeded = true;
+
+ // If we run out of data, the ICO decoder will get resumed when there's more
+ // data available, as usual, so we don't need the contained decoder to get
+ // resumed too. To avoid that, we provide an IResumable which just does
+ // nothing. All the caller needs to do is flush when there is new data.
+ LexerResult result = mContainedDecoder->Decode();
+ if (result == LexerResult(TerminalState::FAILURE)) {
+ succeeded = false;
+ }
+
+ MOZ_ASSERT(result != LexerResult(Yield::OUTPUT_AVAILABLE),
+ "Unexpected yield");
+
+ // Make our state the same as the state of the contained decoder, and
+ // propagate errors.
+ mProgress |= mContainedDecoder->TakeProgress();
+ mInvalidRect.UnionRect(mInvalidRect, mContainedDecoder->TakeInvalidRect());
+ if (mContainedDecoder->HasError()) {
+ succeeded = false;
+ }
+
+ return succeeded;
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/decoders/nsICODecoder.h b/image/decoders/nsICODecoder.h
new file mode 100644
index 0000000000..4e2665334e
--- /dev/null
+++ b/image/decoders/nsICODecoder.h
@@ -0,0 +1,106 @@
+/* vim:set tw=80 expandtab softtabstop=4 ts=4 sw=2: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_nsICODecoder_h
+#define mozilla_image_decoders_nsICODecoder_h
+
+#include "StreamingLexer.h"
+#include "Decoder.h"
+#include "Downscaler.h"
+#include "imgFrame.h"
+#include "mozilla/gfx/2D.h"
+#include "nsBMPDecoder.h"
+#include "nsPNGDecoder.h"
+#include "ICOFileHeaders.h"
+
+namespace mozilla {
+namespace image {
+
+class RasterImage;
+
+enum class ICOState {
+ HEADER,
+ DIR_ENTRY,
+ FINISHED_DIR_ENTRY,
+ ITERATE_UNSIZED_DIR_ENTRY,
+ SKIP_TO_RESOURCE,
+ FOUND_RESOURCE,
+ SNIFF_RESOURCE,
+ READ_RESOURCE,
+ PREPARE_FOR_MASK,
+ READ_MASK_ROW,
+ FINISH_MASK,
+ SKIP_MASK,
+ FINISHED_RESOURCE
+};
+
+class nsICODecoder : public Decoder {
+ public:
+ virtual ~nsICODecoder() {}
+
+ /// @return The offset from the beginning of the ICO to the first resource.
+ size_t FirstResourceOffset() const;
+
+ DecoderType GetType() const override { return DecoderType::ICO; }
+ LexerResult DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) override;
+ nsresult FinishInternal() override;
+ nsresult FinishWithErrorInternal() override;
+
+ private:
+ friend class DecoderFactory;
+
+ // Decoders should only be instantiated via DecoderFactory.
+ explicit nsICODecoder(RasterImage* aImage);
+
+ // Flushes the contained decoder to read all available data and sets the
+ // appropriate errors. Returns true if there are no errors.
+ bool FlushContainedDecoder();
+
+ // Gets decoder state from the contained decoder so it's visible externally.
+ nsresult GetFinalStateFromContainedDecoder();
+
+ // Obtains the number of colors from the BPP, mBPP must be filled in
+ uint16_t GetNumColors();
+
+ LexerTransition<ICOState> ReadHeader(const char* aData);
+ LexerTransition<ICOState> ReadDirEntry(const char* aData);
+ LexerTransition<ICOState> IterateUnsizedDirEntry();
+ LexerTransition<ICOState> FinishDirEntry();
+ LexerTransition<ICOState> SniffResource(const char* aData);
+ LexerTransition<ICOState> ReadResource();
+ LexerTransition<ICOState> ReadBIH(const char* aData);
+ LexerTransition<ICOState> PrepareForMask();
+ LexerTransition<ICOState> ReadMaskRow(const char* aData);
+ LexerTransition<ICOState> FinishMask();
+ LexerTransition<ICOState> FinishResource();
+
+ struct IconDirEntryEx : public IconDirEntry {
+ OrientedIntSize mSize;
+ };
+
+ StreamingLexer<ICOState, 32> mLexer; // The lexer.
+ Maybe<Downscaler> mDownscaler; // The downscaler used for the mask.
+ RefPtr<Decoder> mContainedDecoder; // Either a BMP or PNG decoder.
+ Maybe<SourceBufferIterator>
+ mReturnIterator; // Iterator to save return point.
+ UniquePtr<uint8_t[]> mMaskBuffer; // A temporary buffer for the alpha mask.
+ nsTArray<IconDirEntryEx> mDirEntries; // Valid dir entries with a size.
+ nsTArray<IconDirEntryEx> mUnsizedDirEntries; // Dir entries without a size.
+ IconDirEntryEx* mDirEntry; // The dir entry for the selected resource.
+ uint16_t mNumIcons; // Stores the number of icons in the ICO file.
+ uint16_t mCurrIcon; // Stores the current dir entry index we are processing.
+ uint16_t mBPP; // The BPP of the resource we're decoding.
+ uint32_t
+ mMaskRowSize; // The size in bytes of each row in the BMP alpha mask.
+ uint32_t mCurrMaskLine; // The line of the BMP alpha mask we're processing.
+ bool mIsCursor; // Is this ICO a cursor?
+ bool mHasMaskAlpha; // Did the BMP alpha mask have any transparency?
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_decoders_nsICODecoder_h
diff --git a/image/decoders/nsIconDecoder.cpp b/image/decoders/nsIconDecoder.cpp
new file mode 100644
index 0000000000..c4ed8b7b06
--- /dev/null
+++ b/image/decoders/nsIconDecoder.cpp
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIconDecoder.h"
+#include "RasterImage.h"
+#include "SurfacePipeFactory.h"
+#include "gfxPlatform.h"
+
+using namespace mozilla::gfx;
+
+namespace mozilla {
+namespace image {
+
+static const uint32_t ICON_HEADER_SIZE = 4;
+
+nsIconDecoder::nsIconDecoder(RasterImage* aImage)
+ : Decoder(aImage),
+ mLexer(Transition::To(State::HEADER, ICON_HEADER_SIZE),
+ Transition::TerminateSuccess()),
+ mBytesPerRow() // set by ReadHeader()
+{
+ // Nothing to do
+}
+
+nsIconDecoder::~nsIconDecoder() {}
+
+LexerResult nsIconDecoder::DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) {
+ MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
+
+ return mLexer.Lex(aIterator, aOnResume,
+ [=](State aState, const char* aData, size_t aLength) {
+ switch (aState) {
+ case State::HEADER:
+ return ReadHeader(aData);
+ case State::ROW_OF_PIXELS:
+ return ReadRowOfPixels(aData, aLength);
+ case State::FINISH:
+ return Finish();
+ default:
+ MOZ_CRASH("Unknown State");
+ }
+ });
+}
+
+LexerTransition<nsIconDecoder::State> nsIconDecoder::ReadHeader(
+ const char* aData) {
+ // Grab the width and height.
+ uint8_t width = uint8_t(aData[0]);
+ uint8_t height = uint8_t(aData[1]);
+ SurfaceFormat format = SurfaceFormat(aData[2]);
+ bool transform = bool(aData[3]);
+
+ // FIXME(aosmond): On OSX we get the icon in device space and already
+ // premultiplied, so we can't support the surface flags with icons right now.
+ SurfacePipeFlags pipeFlags = SurfacePipeFlags();
+ if (transform) {
+ if (mCMSMode == CMSMode::All) {
+ mTransform = GetCMSsRGBTransform(format);
+ }
+
+ if (!(GetSurfaceFlags() & SurfaceFlags::NO_PREMULTIPLY_ALPHA)) {
+ pipeFlags |= SurfacePipeFlags::PREMULTIPLY_ALPHA;
+ }
+ }
+
+ // The input is 32bpp, so we expect 4 bytes of data per pixel.
+ mBytesPerRow = width * 4;
+
+ // Post our size to the superclass.
+ PostSize(width, height);
+
+ // Icons have alpha.
+ PostHasTransparency();
+
+ // If we're doing a metadata decode, we're done.
+ if (IsMetadataDecode()) {
+ return Transition::TerminateSuccess();
+ }
+
+ MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
+ Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
+ this, Size(), OutputSize(), FullFrame(), format, SurfaceFormat::OS_RGBA,
+ /* aAnimParams */ Nothing(), mTransform, pipeFlags);
+ if (!pipe) {
+ return Transition::TerminateFailure();
+ }
+
+ mPipe = std::move(*pipe);
+
+ MOZ_ASSERT(mImageData, "Should have a buffer now");
+
+ return Transition::To(State::ROW_OF_PIXELS, mBytesPerRow);
+}
+
+LexerTransition<nsIconDecoder::State> nsIconDecoder::ReadRowOfPixels(
+ const char* aData, size_t aLength) {
+ MOZ_ASSERT(aLength % 4 == 0, "Rows should contain a multiple of four bytes");
+
+ auto result = mPipe.WriteBuffer(reinterpret_cast<const uint32_t*>(aData));
+ MOZ_ASSERT(result != WriteState::FAILURE);
+
+ Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect();
+ if (invalidRect) {
+ PostInvalidation(invalidRect->mInputSpaceRect,
+ Some(invalidRect->mOutputSpaceRect));
+ }
+
+ return result == WriteState::FINISHED
+ ? Transition::To(State::FINISH, 0)
+ : Transition::To(State::ROW_OF_PIXELS, mBytesPerRow);
+}
+
+LexerTransition<nsIconDecoder::State> nsIconDecoder::Finish() {
+ PostFrameStop();
+ PostDecodeDone();
+
+ return Transition::TerminateSuccess();
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/decoders/nsIconDecoder.h b/image/decoders/nsIconDecoder.h
new file mode 100644
index 0000000000..73bc1b5731
--- /dev/null
+++ b/image/decoders/nsIconDecoder.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_nsIconDecoder_h
+#define mozilla_image_decoders_nsIconDecoder_h
+
+#include "Decoder.h"
+#include "StreamingLexer.h"
+#include "SurfacePipe.h"
+
+namespace mozilla {
+namespace image {
+
+class RasterImage;
+
+////////////////////////////////////////////////////////////////////////////////
+// The icon decoder is a decoder specifically tailored for loading icons
+// from the OS. We've defined our own little format to represent these icons
+// and this decoder takes that format and converts it into 24-bit RGB with
+// alpha channel support. It was modeled a bit off the PPM decoder.
+//
+// The format of the incoming data is as follows:
+//
+// The first two bytes contain the width and the height of the icon.
+// The remaining bytes contain the icon data, 4 bytes per pixel, in
+// ARGB order (platform endianness, A in highest bits, B in lowest
+// bits), row-primary, top-to-bottom, left-to-right, with
+// premultiplied alpha.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+class nsIconDecoder : public Decoder {
+ public:
+ virtual ~nsIconDecoder();
+
+ DecoderType GetType() const override { return DecoderType::ICON; }
+
+ LexerResult DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) override;
+
+ private:
+ friend class DecoderFactory;
+
+ // Decoders should only be instantiated via DecoderFactory.
+ explicit nsIconDecoder(RasterImage* aImage);
+
+ enum class State { HEADER, ROW_OF_PIXELS, FINISH };
+
+ LexerTransition<State> ReadHeader(const char* aData);
+ LexerTransition<State> ReadRowOfPixels(const char* aData, size_t aLength);
+ LexerTransition<State> Finish();
+
+ StreamingLexer<State> mLexer;
+ SurfacePipe mPipe;
+ uint32_t mBytesPerRow;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_decoders_nsIconDecoder_h
diff --git a/image/decoders/nsJPEGDecoder.cpp b/image/decoders/nsJPEGDecoder.cpp
new file mode 100644
index 0000000000..0a9c2cc478
--- /dev/null
+++ b/image/decoders/nsJPEGDecoder.cpp
@@ -0,0 +1,999 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageLogging.h" // Must appear first.
+
+#include "nsJPEGDecoder.h"
+
+#include <cstdint>
+
+#include "imgFrame.h"
+#include "Orientation.h"
+#include "EXIF.h"
+#include "SurfacePipeFactory.h"
+
+#include "nspr.h"
+#include "nsCRT.h"
+#include "gfxColor.h"
+
+#include "jerror.h"
+
+#include "gfxPlatform.h"
+#include "mozilla/EndianUtils.h"
+#include "mozilla/gfx/Types.h"
+#include "mozilla/Telemetry.h"
+
+extern "C" {
+#include "iccjpeg.h"
+}
+
+#if MOZ_BIG_ENDIAN()
+# define MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB JCS_EXT_XRGB
+#else
+# define MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB JCS_EXT_BGRX
+#endif
+
+static void cmyk_convert_bgra(uint32_t* aInput, uint32_t* aOutput,
+ int32_t aWidth);
+
+using mozilla::gfx::SurfaceFormat;
+
+namespace mozilla {
+namespace image {
+
+static mozilla::LazyLogModule sJPEGLog("JPEGDecoder");
+
+static mozilla::LazyLogModule sJPEGDecoderAccountingLog(
+ "JPEGDecoderAccounting");
+
+static qcms_profile* GetICCProfile(struct jpeg_decompress_struct& info) {
+ JOCTET* profilebuf;
+ uint32_t profileLength;
+ qcms_profile* profile = nullptr;
+
+ if (read_icc_profile(&info, &profilebuf, &profileLength)) {
+ profile = qcms_profile_from_memory(profilebuf, profileLength);
+ free(profilebuf);
+ }
+
+ return profile;
+}
+
+METHODDEF(void) init_source(j_decompress_ptr jd);
+METHODDEF(boolean) fill_input_buffer(j_decompress_ptr jd);
+METHODDEF(void) skip_input_data(j_decompress_ptr jd, long num_bytes);
+METHODDEF(void) term_source(j_decompress_ptr jd);
+METHODDEF(void) my_error_exit(j_common_ptr cinfo);
+METHODDEF(void) progress_monitor(j_common_ptr info);
+
+// Normal JFIF markers can't have more bytes than this.
+#define MAX_JPEG_MARKER_LENGTH (((uint32_t)1 << 16) - 1)
+
+nsJPEGDecoder::nsJPEGDecoder(RasterImage* aImage,
+ Decoder::DecodeStyle aDecodeStyle)
+ : Decoder(aImage),
+ mLexer(Transition::ToUnbuffered(State::FINISHED_JPEG_DATA,
+ State::JPEG_DATA, SIZE_MAX),
+ Transition::TerminateSuccess()),
+ mProfile(nullptr),
+ mProfileLength(0),
+ mCMSLine(nullptr),
+ mDecodeStyle(aDecodeStyle) {
+ this->mErr.pub.error_exit = nullptr;
+ this->mErr.pub.emit_message = nullptr;
+ this->mErr.pub.output_message = nullptr;
+ this->mErr.pub.format_message = nullptr;
+ this->mErr.pub.reset_error_mgr = nullptr;
+ this->mErr.pub.msg_code = 0;
+ this->mErr.pub.trace_level = 0;
+ this->mErr.pub.num_warnings = 0;
+ this->mErr.pub.jpeg_message_table = nullptr;
+ this->mErr.pub.last_jpeg_message = 0;
+ this->mErr.pub.addon_message_table = nullptr;
+ this->mErr.pub.first_addon_message = 0;
+ this->mErr.pub.last_addon_message = 0;
+ mState = JPEG_HEADER;
+ mReading = true;
+ mImageData = nullptr;
+
+ mBytesToSkip = 0;
+ memset(&mInfo, 0, sizeof(jpeg_decompress_struct));
+ memset(&mSourceMgr, 0, sizeof(mSourceMgr));
+ memset(&mProgressMgr, 0, sizeof(mProgressMgr));
+ mInfo.client_data = (void*)this;
+
+ mSegment = nullptr;
+ mSegmentLen = 0;
+
+ mBackBuffer = nullptr;
+ mBackBufferLen = mBackBufferSize = mBackBufferUnreadLen = 0;
+
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("nsJPEGDecoder::nsJPEGDecoder: Creating JPEG decoder %p", this));
+}
+
+nsJPEGDecoder::~nsJPEGDecoder() {
+ // Step 8: Release JPEG decompression object
+ mInfo.src = nullptr;
+ jpeg_destroy_decompress(&mInfo);
+
+ free(mBackBuffer);
+ mBackBuffer = nullptr;
+
+ delete[] mCMSLine;
+
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("nsJPEGDecoder::~nsJPEGDecoder: Destroying JPEG decoder %p", this));
+}
+
+Maybe<Telemetry::HistogramID> nsJPEGDecoder::SpeedHistogram() const {
+ return Some(Telemetry::IMAGE_DECODE_SPEED_JPEG);
+}
+
+nsresult nsJPEGDecoder::InitInternal() {
+ // We set up the normal JPEG error routines, then override error_exit.
+ mInfo.err = jpeg_std_error(&mErr.pub);
+ // mInfo.err = jpeg_std_error(&mErr.pub);
+ mErr.pub.error_exit = my_error_exit;
+ // Establish the setjmp return context for my_error_exit to use.
+ if (setjmp(mErr.setjmp_buffer)) {
+ // If we get here, the JPEG code has signaled an error, and initialization
+ // has failed.
+ return NS_ERROR_FAILURE;
+ }
+
+ // Step 1: allocate and initialize JPEG decompression object
+ jpeg_create_decompress(&mInfo);
+ // Set the source manager
+ mInfo.src = &mSourceMgr;
+
+ // Step 2: specify data source (eg, a file)
+
+ // Setup callback functions.
+ mSourceMgr.init_source = init_source;
+ mSourceMgr.fill_input_buffer = fill_input_buffer;
+ mSourceMgr.skip_input_data = skip_input_data;
+ mSourceMgr.resync_to_restart = jpeg_resync_to_restart;
+ mSourceMgr.term_source = term_source;
+
+ mInfo.mem->max_memory_to_use = static_cast<long>(
+ std::min<size_t>(SurfaceCache::MaximumCapacity(), LONG_MAX));
+
+ mProgressMgr.progress_monitor = &progress_monitor;
+ mInfo.progress = &mProgressMgr;
+
+ // Record app markers for ICC data
+ for (uint32_t m = 0; m < 16; m++) {
+ jpeg_save_markers(&mInfo, JPEG_APP0 + m, 0xFFFF);
+ }
+
+ return NS_OK;
+}
+
+nsresult nsJPEGDecoder::FinishInternal() {
+ // If we're not in any sort of error case, force our state to JPEG_DONE.
+ if ((mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER) &&
+ (mState != JPEG_ERROR) && !IsMetadataDecode()) {
+ mState = JPEG_DONE;
+ }
+
+ return NS_OK;
+}
+
+LexerResult nsJPEGDecoder::DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) {
+ MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
+
+ return mLexer.Lex(aIterator, aOnResume,
+ [=](State aState, const char* aData, size_t aLength) {
+ switch (aState) {
+ case State::JPEG_DATA:
+ return ReadJPEGData(aData, aLength);
+ case State::FINISHED_JPEG_DATA:
+ return FinishedJPEGData();
+ }
+ MOZ_CRASH("Unknown State");
+ });
+}
+
+LexerTransition<nsJPEGDecoder::State> nsJPEGDecoder::ReadJPEGData(
+ const char* aData, size_t aLength) {
+ mSegment = reinterpret_cast<const JOCTET*>(aData);
+ mSegmentLen = aLength;
+
+ // Return here if there is a error within libjpeg.
+ nsresult error_code;
+ // This cast to nsresult makes sense because setjmp() returns whatever we
+ // passed to longjmp(), which was actually an nsresult. These error codes
+ // have been translated from libjpeg error codes, like so:
+ // JERR_OUT_OF_MEMORY => NS_ERROR_OUT_OF_MEMORY
+ // JERR_UNKNOWN_MARKER => NS_ERROR_ILLEGAL_VALUE
+ // JERR_SOF_UNSUPPORTED => NS_ERROR_INVALID_CONTENT_ENCODING
+ // <any other error> => NS_ERROR_FAILURE
+ if ((error_code = static_cast<nsresult>(setjmp(mErr.setjmp_buffer))) !=
+ NS_OK) {
+ bool fatal = true;
+ if (error_code == NS_ERROR_FAILURE) {
+ // Error due to corrupt data. Make sure that we don't feed any more data
+ // to libjpeg-turbo.
+ mState = JPEG_SINK_NON_JPEG_TRAILER;
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (setjmp returned NS_ERROR_FAILURE)"));
+ } else if (error_code == NS_ERROR_ILLEGAL_VALUE) {
+ // This is a recoverable error. Consume the marker and continue.
+ mInfo.unread_marker = 0;
+ fatal = false;
+ } else if (error_code == NS_ERROR_INVALID_CONTENT_ENCODING) {
+ // The content is encoding frames with a format that libjpeg can't handle.
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (setjmp returned NS_ERROR_INVALID_CONTENT_ENCODING)"));
+ // Check to see if we're in the done state, which indicates that we've
+ // already processed the main JPEG data.
+ bool inDoneState = (mState == JPEG_DONE);
+ // Whether we succeed or fail, we shouldn't send any more data.
+ mState = JPEG_SINK_NON_JPEG_TRAILER;
+
+ // If we're in the done state, we exit successfully and attempt to
+ // display the content we've already received. Otherwise, we fallthrough
+ // and treat this as a fatal error.
+ if (inDoneState) {
+ return Transition::TerminateSuccess();
+ }
+ } else {
+ // Error for another reason. (Possibly OOM.)
+ mState = JPEG_ERROR;
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (setjmp returned an error)"));
+ }
+
+ if (fatal) {
+ return Transition::TerminateFailure();
+ }
+ }
+
+ MOZ_LOG(sJPEGLog, LogLevel::Debug,
+ ("[this=%p] nsJPEGDecoder::Write -- processing JPEG data\n", this));
+
+ switch (mState) {
+ case JPEG_HEADER: {
+ LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
+ "nsJPEGDecoder::Write -- entering JPEG_HEADER"
+ " case");
+
+ // Step 3: read file parameters with jpeg_read_header()
+ if (jpeg_read_header(&mInfo, TRUE) == JPEG_SUSPENDED) {
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (JPEG_SUSPENDED)"));
+ return Transition::ContinueUnbuffered(
+ State::JPEG_DATA); // I/O suspension
+ }
+
+ // Post our size to the superclass
+ EXIFData exif = ReadExifData();
+ PostSize(mInfo.image_width, mInfo.image_height, exif.orientation,
+ exif.resolution);
+ if (HasError()) {
+ // Setting the size led to an error.
+ mState = JPEG_ERROR;
+ return Transition::TerminateFailure();
+ }
+
+ // If we're doing a metadata decode, we're done.
+ if (IsMetadataDecode()) {
+ return Transition::TerminateSuccess();
+ }
+
+ // We're doing a full decode.
+ switch (mInfo.jpeg_color_space) {
+ case JCS_GRAYSCALE:
+ case JCS_RGB:
+ case JCS_YCbCr:
+ // By default, we will output directly to BGRA. If we need to apply
+ // special color transforms, this may change.
+ switch (SurfaceFormat::OS_RGBX) {
+ case SurfaceFormat::B8G8R8X8:
+ mInfo.out_color_space = JCS_EXT_BGRX;
+ break;
+ case SurfaceFormat::X8R8G8B8:
+ mInfo.out_color_space = JCS_EXT_XRGB;
+ break;
+ case SurfaceFormat::R8G8B8X8:
+ mInfo.out_color_space = JCS_EXT_RGBX;
+ break;
+ default:
+ mState = JPEG_ERROR;
+ return Transition::TerminateFailure();
+ }
+ break;
+ case JCS_CMYK:
+ case JCS_YCCK:
+ // libjpeg can convert from YCCK to CMYK, but not to XRGB.
+ mInfo.out_color_space = JCS_CMYK;
+ break;
+ default:
+ mState = JPEG_ERROR;
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (unknown colorspace (3))"));
+ return Transition::TerminateFailure();
+ }
+
+ if (mCMSMode != CMSMode::Off) {
+ if ((mInProfile = GetICCProfile(mInfo)) != nullptr &&
+ GetCMSOutputProfile()) {
+ uint32_t profileSpace = qcms_profile_get_color_space(mInProfile);
+
+ qcms_data_type outputType = gfxPlatform::GetCMSOSRGBAType();
+ Maybe<qcms_data_type> inputType;
+ if (profileSpace == icSigRgbData) {
+ // We can always color manage RGB profiles since it happens at the
+ // end of the pipeline.
+ inputType.emplace(outputType);
+ } else if (profileSpace == icSigGrayData &&
+ mInfo.jpeg_color_space == JCS_GRAYSCALE) {
+ // We can only color manage gray profiles if the original color
+ // space is grayscale. This means we must downscale after color
+ // management since the downscaler assumes BGRA.
+ mInfo.out_color_space = JCS_GRAYSCALE;
+ inputType.emplace(QCMS_DATA_GRAY_8);
+ }
+
+#if 0
+ // We don't currently support CMYK profiles. The following
+ // code dealt with lcms types. Add something like this
+ // back when we gain support for CMYK.
+
+ // Adobe Photoshop writes YCCK/CMYK files with inverted data
+ if (mInfo.out_color_space == JCS_CMYK) {
+ type |= FLAVOR_SH(mInfo.saw_Adobe_marker ? 1 : 0);
+ }
+#endif
+
+ if (inputType) {
+ // Calculate rendering intent.
+ int intent = gfxPlatform::GetRenderingIntent();
+ if (intent == -1) {
+ intent = qcms_profile_get_rendering_intent(mInProfile);
+ }
+
+ // Create the color management transform.
+ mTransform = qcms_transform_create(mInProfile, *inputType,
+ GetCMSOutputProfile(),
+ outputType, (qcms_intent)intent);
+ }
+ } else if (mCMSMode == CMSMode::All) {
+ mTransform = GetCMSsRGBTransform(SurfaceFormat::OS_RGBX);
+ }
+ }
+
+ // We don't want to use the pipe buffers directly because we don't want
+ // any reads on non-BGRA formatted data.
+ if (mInfo.out_color_space == JCS_GRAYSCALE ||
+ mInfo.out_color_space == JCS_CMYK) {
+ mCMSLine = new (std::nothrow) uint32_t[mInfo.image_width];
+ if (!mCMSLine) {
+ mState = JPEG_ERROR;
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (could allocate buffer for color conversion)"));
+ return Transition::TerminateFailure();
+ }
+ }
+
+ // Don't allocate a giant and superfluous memory buffer
+ // when not doing a progressive decode.
+ mInfo.buffered_image =
+ mDecodeStyle == PROGRESSIVE && jpeg_has_multiple_scans(&mInfo);
+
+ /* Used to set up image size so arrays can be allocated */
+ jpeg_calc_output_dimensions(&mInfo);
+
+ // We handle the transform outside the pipeline if we are outputting in
+ // grayscale, because the pipeline wants BGRA pixels, particularly the
+ // downscaling filter, so we can't handle it after downscaling as would
+ // be optimal.
+ qcms_transform* pipeTransform =
+ mInfo.out_color_space != JCS_GRAYSCALE ? mTransform : nullptr;
+
+ Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateReorientSurfacePipe(
+ this, Size(), OutputSize(), SurfaceFormat::OS_RGBX, pipeTransform,
+ GetOrientation());
+ if (!pipe) {
+ mState = JPEG_ERROR;
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (could not initialize surface pipe)"));
+ return Transition::TerminateFailure();
+ }
+
+ mPipe = std::move(*pipe);
+
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ (" JPEGDecoderAccounting: nsJPEGDecoder::"
+ "Write -- created image frame with %ux%u pixels",
+ mInfo.image_width, mInfo.image_height));
+
+ mState = JPEG_START_DECOMPRESS;
+ [[fallthrough]]; // to start decompressing.
+ }
+
+ case JPEG_START_DECOMPRESS: {
+ LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
+ "nsJPEGDecoder::Write -- entering"
+ " JPEG_START_DECOMPRESS case");
+ // Step 4: set parameters for decompression
+
+ // FIXME -- Should reset dct_method and dither mode
+ // for final pass of progressive JPEG
+
+ mInfo.dct_method = JDCT_ISLOW;
+ mInfo.dither_mode = JDITHER_FS;
+ mInfo.do_fancy_upsampling = TRUE;
+ mInfo.enable_2pass_quant = FALSE;
+ mInfo.do_block_smoothing = TRUE;
+
+ // Step 5: Start decompressor
+ if (jpeg_start_decompress(&mInfo) == FALSE) {
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (I/O suspension after jpeg_start_decompress())"));
+ return Transition::ContinueUnbuffered(
+ State::JPEG_DATA); // I/O suspension
+ }
+
+ // If this is a progressive JPEG ...
+ mState = mInfo.buffered_image ? JPEG_DECOMPRESS_PROGRESSIVE
+ : JPEG_DECOMPRESS_SEQUENTIAL;
+ [[fallthrough]]; // to decompress sequential JPEG.
+ }
+
+ case JPEG_DECOMPRESS_SEQUENTIAL: {
+ if (mState == JPEG_DECOMPRESS_SEQUENTIAL) {
+ LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
+ "nsJPEGDecoder::Write -- "
+ "JPEG_DECOMPRESS_SEQUENTIAL case");
+
+ switch (OutputScanlines()) {
+ case WriteState::NEED_MORE_DATA:
+ MOZ_LOG(
+ sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (I/O suspension after OutputScanlines() - SEQUENTIAL)"));
+ return Transition::ContinueUnbuffered(
+ State::JPEG_DATA); // I/O suspension
+ case WriteState::FINISHED:
+ NS_ASSERTION(mInfo.output_scanline == mInfo.output_height,
+ "We didn't process all of the data!");
+ mState = JPEG_DONE;
+ break;
+ case WriteState::FAILURE:
+ mState = JPEG_ERROR;
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (Error in pipeline from OutputScalines())"));
+ return Transition::TerminateFailure();
+ }
+ }
+ [[fallthrough]]; // to decompress progressive JPEG.
+ }
+
+ case JPEG_DECOMPRESS_PROGRESSIVE: {
+ if (mState == JPEG_DECOMPRESS_PROGRESSIVE) {
+ LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
+ "nsJPEGDecoder::Write -- JPEG_DECOMPRESS_PROGRESSIVE case");
+ auto AllComponentsSeen = [](jpeg_decompress_struct& info) {
+ bool all_components_seen = true;
+ if (info.coef_bits) {
+ for (int c = 0; c < info.num_components; ++c) {
+ bool current_component_seen = info.coef_bits[c][0] != -1;
+ all_components_seen &= current_component_seen;
+ }
+ }
+ return all_components_seen;
+ };
+ int status;
+ int scan_to_display_first = 0;
+ bool all_components_seen;
+ all_components_seen = AllComponentsSeen(mInfo);
+ if (all_components_seen) {
+ scan_to_display_first = mInfo.input_scan_number;
+ }
+
+ do {
+ status = jpeg_consume_input(&mInfo);
+
+ if (status == JPEG_REACHED_SOS || status == JPEG_REACHED_EOI ||
+ status == JPEG_SUSPENDED) {
+ // record the first scan where all components are present
+ all_components_seen = AllComponentsSeen(mInfo);
+ if (!scan_to_display_first && all_components_seen) {
+ scan_to_display_first = mInfo.input_scan_number;
+ }
+ }
+ } while ((status != JPEG_SUSPENDED) && (status != JPEG_REACHED_EOI));
+
+ if (!all_components_seen) {
+ return Transition::ContinueUnbuffered(
+ State::JPEG_DATA); // I/O suspension
+ }
+ // make sure we never try to access the non-exsitent scan 0
+ if (!scan_to_display_first) {
+ scan_to_display_first = 1;
+ }
+ while (mState != JPEG_DONE) {
+ if (mInfo.output_scanline == 0) {
+ int scan = mInfo.input_scan_number;
+
+ // if we haven't displayed anything yet (output_scan_number==0)
+ // and we have enough data for a complete scan, force output
+ // of the last full scan, but only if this last scan has seen
+ // DC data from all components
+ if ((mInfo.output_scan_number == 0) &&
+ (scan > scan_to_display_first) &&
+ (status != JPEG_REACHED_EOI)) {
+ scan--;
+ }
+ MOZ_ASSERT(scan > 0, "scan number to small!");
+ if (!jpeg_start_output(&mInfo, scan)) {
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (I/O suspension after jpeg_start_output() -"
+ " PROGRESSIVE)"));
+ return Transition::ContinueUnbuffered(
+ State::JPEG_DATA); // I/O suspension
+ }
+ }
+
+ if (mInfo.output_scanline == 0xffffff) {
+ mInfo.output_scanline = 0;
+ }
+
+ switch (OutputScanlines()) {
+ case WriteState::NEED_MORE_DATA:
+ if (mInfo.output_scanline == 0) {
+ // didn't manage to read any lines - flag so we don't call
+ // jpeg_start_output() multiple times for the same scan
+ mInfo.output_scanline = 0xffffff;
+ }
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (I/O suspension after OutputScanlines() - "
+ "PROGRESSIVE)"));
+ return Transition::ContinueUnbuffered(
+ State::JPEG_DATA); // I/O suspension
+ case WriteState::FINISHED:
+ NS_ASSERTION(mInfo.output_scanline == mInfo.output_height,
+ "We didn't process all of the data!");
+
+ if (!jpeg_finish_output(&mInfo)) {
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (I/O suspension after jpeg_finish_output() -"
+ " PROGRESSIVE)"));
+ return Transition::ContinueUnbuffered(
+ State::JPEG_DATA); // I/O suspension
+ }
+
+ if (jpeg_input_complete(&mInfo) &&
+ (mInfo.input_scan_number == mInfo.output_scan_number)) {
+ mState = JPEG_DONE;
+ } else {
+ mInfo.output_scanline = 0;
+ mPipe.ResetToFirstRow();
+ }
+ break;
+ case WriteState::FAILURE:
+ mState = JPEG_ERROR;
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (Error in pipeline from OutputScalines())"));
+ return Transition::TerminateFailure();
+ }
+ }
+ }
+ [[fallthrough]]; // to finish decompressing.
+ }
+
+ case JPEG_DONE: {
+ LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
+ "nsJPEGDecoder::ProcessData -- entering"
+ " JPEG_DONE case");
+
+ // Step 7: Finish decompression
+
+ if (jpeg_finish_decompress(&mInfo) == FALSE) {
+ MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
+ ("} (I/O suspension after jpeg_finish_decompress() - DONE)"));
+ return Transition::ContinueUnbuffered(
+ State::JPEG_DATA); // I/O suspension
+ }
+
+ // Make sure we don't feed any more data to libjpeg-turbo.
+ mState = JPEG_SINK_NON_JPEG_TRAILER;
+
+ // We're done.
+ return Transition::TerminateSuccess();
+ }
+ case JPEG_SINK_NON_JPEG_TRAILER:
+ MOZ_LOG(sJPEGLog, LogLevel::Debug,
+ ("[this=%p] nsJPEGDecoder::ProcessData -- entering"
+ " JPEG_SINK_NON_JPEG_TRAILER case\n",
+ this));
+
+ MOZ_ASSERT_UNREACHABLE(
+ "Should stop getting data after entering state "
+ "JPEG_SINK_NON_JPEG_TRAILER");
+
+ return Transition::TerminateSuccess();
+
+ case JPEG_ERROR:
+ MOZ_ASSERT_UNREACHABLE(
+ "Should stop getting data after entering state "
+ "JPEG_ERROR");
+
+ return Transition::TerminateFailure();
+ }
+
+ MOZ_ASSERT_UNREACHABLE("Escaped the JPEG decoder state machine");
+ return Transition::TerminateFailure();
+} // namespace image
+
+LexerTransition<nsJPEGDecoder::State> nsJPEGDecoder::FinishedJPEGData() {
+ // Since we set up an unbuffered read for SIZE_MAX bytes, if we actually read
+ // all that data something is really wrong.
+ MOZ_ASSERT_UNREACHABLE("Read the entire address space?");
+ return Transition::TerminateFailure();
+}
+
+EXIFData nsJPEGDecoder::ReadExifData() const {
+ jpeg_saved_marker_ptr marker;
+
+ // Locate the APP1 marker, where EXIF data is stored, in the marker list.
+ for (marker = mInfo.marker_list; marker != nullptr; marker = marker->next) {
+ if (marker->marker == JPEG_APP0 + 1) {
+ break;
+ }
+ }
+
+ // If we're at the end of the list, there's no EXIF data.
+ if (!marker) {
+ return EXIFData();
+ }
+
+ return EXIFParser::Parse(marker->data,
+ static_cast<uint32_t>(marker->data_length),
+ gfx::IntSize(mInfo.image_width, mInfo.image_height));
+}
+
+void nsJPEGDecoder::NotifyDone() {
+ PostFrameStop(Opacity::FULLY_OPAQUE);
+ PostDecodeDone();
+}
+
+WriteState nsJPEGDecoder::OutputScanlines() {
+ auto result = mPipe.WritePixelBlocks<uint32_t>(
+ [&](uint32_t* aPixelBlock, int32_t aBlockSize) {
+ JSAMPROW sampleRow = (JSAMPROW)(mCMSLine ? mCMSLine : aPixelBlock);
+ if (jpeg_read_scanlines(&mInfo, &sampleRow, 1) != 1) {
+ return std::make_tuple(/* aWritten */ 0,
+ Some(WriteState::NEED_MORE_DATA));
+ }
+
+ switch (mInfo.out_color_space) {
+ default:
+ // Already outputted directly to aPixelBlock as BGRA.
+ MOZ_ASSERT(!mCMSLine);
+ break;
+ case JCS_GRAYSCALE:
+ // The transform here does both color management, and converts the
+ // pixels from grayscale to BGRA. This is why we do it here, instead
+ // of using ColorManagementFilter in the SurfacePipe, because the
+ // other filters (e.g. DownscalingFilter) require BGRA pixels.
+ MOZ_ASSERT(mCMSLine);
+ qcms_transform_data(mTransform, mCMSLine, aPixelBlock,
+ mInfo.output_width);
+ break;
+ case JCS_CMYK:
+ // Convert from CMYK to BGRA
+ MOZ_ASSERT(mCMSLine);
+ cmyk_convert_bgra(mCMSLine, aPixelBlock, aBlockSize);
+ break;
+ }
+
+ return std::make_tuple(aBlockSize, Maybe<WriteState>());
+ });
+
+ Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect();
+ if (invalidRect) {
+ PostInvalidation(invalidRect->mInputSpaceRect,
+ Some(invalidRect->mOutputSpaceRect));
+ }
+
+ return result;
+}
+
+// Override the standard error method in the IJG JPEG decoder code.
+METHODDEF(void)
+my_error_exit(j_common_ptr cinfo) {
+ decoder_error_mgr* err = (decoder_error_mgr*)cinfo->err;
+
+ // Convert error to a browser error code
+ nsresult error_code;
+ switch (err->pub.msg_code) {
+ case JERR_OUT_OF_MEMORY:
+ error_code = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ case JERR_UNKNOWN_MARKER:
+ error_code = NS_ERROR_ILLEGAL_VALUE;
+ break;
+ case JERR_SOF_UNSUPPORTED:
+ error_code = NS_ERROR_INVALID_CONTENT_ENCODING;
+ break;
+ default:
+ error_code = NS_ERROR_FAILURE;
+ }
+
+#ifdef DEBUG
+ char buffer[JMSG_LENGTH_MAX];
+
+ // Create the message
+ (*err->pub.format_message)(cinfo, buffer);
+
+ fprintf(stderr, "JPEG decoding error:\n%s\n", buffer);
+#endif
+
+ // Return control to the setjmp point. We pass an nsresult masquerading as
+ // an int, which works because the setjmp() caller casts it back.
+ longjmp(err->setjmp_buffer, static_cast<int>(error_code));
+}
+
+static void progress_monitor(j_common_ptr info) {
+ int scan = ((j_decompress_ptr)info)->input_scan_number;
+ // Progressive images with a very large number of scans can cause the decoder
+ // to hang. Here we use the progress monitor to abort on a very large number
+ // of scans. 1000 is arbitrary, but much larger than the number of scans we
+ // might expect in a normal image.
+ if (scan >= 1000) {
+ my_error_exit(info);
+ }
+}
+
+/*******************************************************************************
+ * This is the callback routine from the IJG JPEG library used to supply new
+ * data to the decompressor when its input buffer is exhausted. It juggles
+ * multiple buffers in an attempt to avoid unnecessary copying of input data.
+ *
+ * (A simpler scheme is possible: It's much easier to use only a single
+ * buffer; when fill_input_buffer() is called, move any unconsumed data
+ * (beyond the current pointer/count) down to the beginning of this buffer and
+ * then load new data into the remaining buffer space. This approach requires
+ * a little more data copying but is far easier to get right.)
+ *
+ * At any one time, the JPEG decompressor is either reading from the necko
+ * input buffer, which is volatile across top-level calls to the IJG library,
+ * or the "backtrack" buffer. The backtrack buffer contains the remaining
+ * unconsumed data from the necko buffer after parsing was suspended due
+ * to insufficient data in some previous call to the IJG library.
+ *
+ * When suspending, the decompressor will back up to a convenient restart
+ * point (typically the start of the current MCU). The variables
+ * next_input_byte & bytes_in_buffer indicate where the restart point will be
+ * if the current call returns FALSE. Data beyond this point must be
+ * rescanned after resumption, so it must be preserved in case the decompressor
+ * decides to backtrack.
+ *
+ * Returns:
+ * TRUE if additional data is available, FALSE if no data present and
+ * the JPEG library should therefore suspend processing of input stream
+ ******************************************************************************/
+
+/******************************************************************************/
+/* data source manager method */
+/******************************************************************************/
+
+/******************************************************************************/
+/* data source manager method
+ Initialize source. This is called by jpeg_read_header() before any
+ data is actually read. May leave
+ bytes_in_buffer set to 0 (in which case a fill_input_buffer() call
+ will occur immediately).
+*/
+METHODDEF(void)
+init_source(j_decompress_ptr jd) {}
+
+/******************************************************************************/
+/* data source manager method
+ Skip num_bytes worth of data. The buffer pointer and count should
+ be advanced over num_bytes input bytes, refilling the buffer as
+ needed. This is used to skip over a potentially large amount of
+ uninteresting data (such as an APPn marker). In some applications
+ it may be possible to optimize away the reading of the skipped data,
+ but it's not clear that being smart is worth much trouble; large
+ skips are uncommon. bytes_in_buffer may be zero on return.
+ A zero or negative skip count should be treated as a no-op.
+*/
+METHODDEF(void)
+skip_input_data(j_decompress_ptr jd, long num_bytes) {
+ struct jpeg_source_mgr* src = jd->src;
+ nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data);
+
+ if (num_bytes > (long)src->bytes_in_buffer) {
+ // Can't skip it all right now until we get more data from
+ // network stream. Set things up so that fill_input_buffer
+ // will skip remaining amount.
+ decoder->mBytesToSkip = (size_t)num_bytes - src->bytes_in_buffer;
+ src->next_input_byte += src->bytes_in_buffer;
+ src->bytes_in_buffer = 0;
+
+ } else {
+ // Simple case. Just advance buffer pointer
+
+ src->bytes_in_buffer -= (size_t)num_bytes;
+ src->next_input_byte += num_bytes;
+ }
+}
+
+/******************************************************************************/
+/* data source manager method
+ This is called whenever bytes_in_buffer has reached zero and more
+ data is wanted. In typical applications, it should read fresh data
+ into the buffer (ignoring the current state of next_input_byte and
+ bytes_in_buffer), reset the pointer & count to the start of the
+ buffer, and return TRUE indicating that the buffer has been reloaded.
+ It is not necessary to fill the buffer entirely, only to obtain at
+ least one more byte. bytes_in_buffer MUST be set to a positive value
+ if TRUE is returned. A FALSE return should only be used when I/O
+ suspension is desired.
+*/
+METHODDEF(boolean)
+fill_input_buffer(j_decompress_ptr jd) {
+ struct jpeg_source_mgr* src = jd->src;
+ nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data);
+
+ if (decoder->mReading) {
+ const JOCTET* new_buffer = decoder->mSegment;
+ uint32_t new_buflen = decoder->mSegmentLen;
+
+ if (!new_buffer || new_buflen == 0) {
+ return false; // suspend
+ }
+
+ decoder->mSegmentLen = 0;
+
+ if (decoder->mBytesToSkip) {
+ if (decoder->mBytesToSkip < new_buflen) {
+ // All done skipping bytes; Return what's left.
+ new_buffer += decoder->mBytesToSkip;
+ new_buflen -= decoder->mBytesToSkip;
+ decoder->mBytesToSkip = 0;
+ } else {
+ // Still need to skip some more data in the future
+ decoder->mBytesToSkip -= (size_t)new_buflen;
+ return false; // suspend
+ }
+ }
+
+ decoder->mBackBufferUnreadLen = src->bytes_in_buffer;
+
+ src->next_input_byte = new_buffer;
+ src->bytes_in_buffer = (size_t)new_buflen;
+ decoder->mReading = false;
+
+ return true;
+ }
+
+ if (src->next_input_byte != decoder->mSegment) {
+ // Backtrack data has been permanently consumed.
+ decoder->mBackBufferUnreadLen = 0;
+ decoder->mBackBufferLen = 0;
+ }
+
+ // Save remainder of netlib buffer in backtrack buffer
+ const uint32_t new_backtrack_buflen =
+ src->bytes_in_buffer + decoder->mBackBufferLen;
+
+ // Make sure backtrack buffer is big enough to hold new data.
+ if (decoder->mBackBufferSize < new_backtrack_buflen) {
+ // Check for malformed MARKER segment lengths, before allocating space
+ // for it
+ if (new_backtrack_buflen > MAX_JPEG_MARKER_LENGTH) {
+ my_error_exit((j_common_ptr)(&decoder->mInfo));
+ }
+
+ // Round up to multiple of 256 bytes.
+ const size_t roundup_buflen = ((new_backtrack_buflen + 255) >> 8) << 8;
+ JOCTET* buf = (JOCTET*)realloc(decoder->mBackBuffer, roundup_buflen);
+ // Check for OOM
+ if (!buf) {
+ decoder->mInfo.err->msg_code = JERR_OUT_OF_MEMORY;
+ my_error_exit((j_common_ptr)(&decoder->mInfo));
+ }
+ decoder->mBackBuffer = buf;
+ decoder->mBackBufferSize = roundup_buflen;
+ }
+
+ // Ensure we actually have a backtrack buffer. Without it, then we know that
+ // there is no data to copy and bytes_in_buffer is already zero.
+ if (decoder->mBackBuffer) {
+ // Copy remainder of netlib segment into backtrack buffer.
+ memmove(decoder->mBackBuffer + decoder->mBackBufferLen,
+ src->next_input_byte, src->bytes_in_buffer);
+ } else {
+ MOZ_ASSERT(src->bytes_in_buffer == 0);
+ MOZ_ASSERT(decoder->mBackBufferLen == 0);
+ MOZ_ASSERT(decoder->mBackBufferUnreadLen == 0);
+ }
+
+ // Point to start of data to be rescanned.
+ src->next_input_byte = decoder->mBackBuffer + decoder->mBackBufferLen -
+ decoder->mBackBufferUnreadLen;
+ src->bytes_in_buffer += decoder->mBackBufferUnreadLen;
+ decoder->mBackBufferLen = (size_t)new_backtrack_buflen;
+ decoder->mReading = true;
+
+ return false;
+}
+
+/******************************************************************************/
+/* data source manager method */
+/*
+ * Terminate source --- called by jpeg_finish_decompress() after all
+ * data has been read to clean up JPEG source manager. NOT called by
+ * jpeg_abort() or jpeg_destroy().
+ */
+METHODDEF(void)
+term_source(j_decompress_ptr jd) {
+ nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data);
+
+ // This function shouldn't be called if we ran into an error we didn't
+ // recover from.
+ MOZ_ASSERT(decoder->mState != JPEG_ERROR,
+ "Calling term_source on a JPEG with mState == JPEG_ERROR!");
+
+ // Notify using a helper method to get around protectedness issues.
+ decoder->NotifyDone();
+}
+
+} // namespace image
+} // namespace mozilla
+
+///*************** Inverted CMYK -> RGB conversion *************************
+/// Input is (Inverted) CMYK stored as 4 bytes per pixel.
+/// Output is RGB stored as 3 bytes per pixel.
+/// @param aInput Points to row buffer containing the CMYK bytes for each pixel
+/// in the row.
+/// @param aOutput Points to row buffer to write BGRA to.
+/// @param aWidth Number of pixels in the row.
+static void cmyk_convert_bgra(uint32_t* aInput, uint32_t* aOutput,
+ int32_t aWidth) {
+ uint8_t* input = reinterpret_cast<uint8_t*>(aInput);
+
+ for (int32_t i = 0; i < aWidth; ++i) {
+ // Source is 'Inverted CMYK', output is RGB.
+ // See: http://www.easyrgb.com/math.php?MATH=M12#text12
+ // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb
+
+ // From CMYK to CMY
+ // C = ( C * ( 1 - K ) + K )
+ // M = ( M * ( 1 - K ) + K )
+ // Y = ( Y * ( 1 - K ) + K )
+
+ // From Inverted CMYK to CMY is thus:
+ // C = ( (1-iC) * (1 - (1-iK)) + (1-iK) ) => 1 - iC*iK
+ // Same for M and Y
+
+ // Convert from CMY (0..1) to RGB (0..1)
+ // R = 1 - C => 1 - (1 - iC*iK) => iC*iK
+ // G = 1 - M => 1 - (1 - iM*iK) => iM*iK
+ // B = 1 - Y => 1 - (1 - iY*iK) => iY*iK
+
+ // Convert from Inverted CMYK (0..255) to RGB (0..255)
+ const uint32_t iC = input[0];
+ const uint32_t iM = input[1];
+ const uint32_t iY = input[2];
+ const uint32_t iK = input[3];
+
+ const uint8_t r = iC * iK / 255;
+ const uint8_t g = iM * iK / 255;
+ const uint8_t b = iY * iK / 255;
+
+ *aOutput++ = (0xFF << mozilla::gfx::SurfaceFormatBit::OS_A) |
+ (r << mozilla::gfx::SurfaceFormatBit::OS_R) |
+ (g << mozilla::gfx::SurfaceFormatBit::OS_G) |
+ (b << mozilla::gfx::SurfaceFormatBit::OS_B);
+ input += 4;
+ }
+}
diff --git a/image/decoders/nsJPEGDecoder.h b/image/decoders/nsJPEGDecoder.h
new file mode 100644
index 0000000000..fa010f9677
--- /dev/null
+++ b/image/decoders/nsJPEGDecoder.h
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_nsJPEGDecoder_h
+#define mozilla_image_decoders_nsJPEGDecoder_h
+
+#include "RasterImage.h"
+#include "SurfacePipe.h"
+#include "EXIF.h"
+
+// On Windows systems, RasterImage.h brings in 'windows.h', which defines INT32.
+// But the jpeg decoder has its own definition of INT32. To avoid build issues,
+// we need to undefine the version from 'windows.h'.
+#undef INT32
+
+#include "Decoder.h"
+
+extern "C" {
+#include "jpeglib.h"
+}
+
+#include <setjmp.h>
+
+namespace mozilla::image {
+
+typedef struct {
+ struct jpeg_error_mgr pub; // "public" fields for IJG library
+ jmp_buf setjmp_buffer; // For handling catastropic errors
+} decoder_error_mgr;
+
+typedef enum {
+ JPEG_HEADER, // Reading JFIF headers
+ JPEG_START_DECOMPRESS,
+ JPEG_DECOMPRESS_PROGRESSIVE, // Output progressive pixels
+ JPEG_DECOMPRESS_SEQUENTIAL, // Output sequential pixels
+ JPEG_DONE,
+ JPEG_SINK_NON_JPEG_TRAILER, // Some image files have a
+ // non-JPEG trailer
+ JPEG_ERROR
+} jstate;
+
+class RasterImage;
+struct Orientation;
+
+class nsJPEGDecoder : public Decoder {
+ public:
+ virtual ~nsJPEGDecoder();
+
+ DecoderType GetType() const override { return DecoderType::JPEG; }
+
+ void NotifyDone();
+
+ protected:
+ nsresult InitInternal() override;
+ LexerResult DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) override;
+ nsresult FinishInternal() override;
+
+ Maybe<Telemetry::HistogramID> SpeedHistogram() const override;
+
+ protected:
+ EXIFData ReadExifData() const;
+ WriteState OutputScanlines();
+
+ private:
+ friend class DecoderFactory;
+
+ // Decoders should only be instantiated via DecoderFactory.
+ nsJPEGDecoder(RasterImage* aImage, Decoder::DecodeStyle aDecodeStyle);
+
+ enum class State { JPEG_DATA, FINISHED_JPEG_DATA };
+
+ void FinishRow(uint32_t aLastSourceRow);
+ LexerTransition<State> ReadJPEGData(const char* aData, size_t aLength);
+ LexerTransition<State> FinishedJPEGData();
+
+ StreamingLexer<State> mLexer;
+
+ public:
+ struct jpeg_decompress_struct mInfo;
+ struct jpeg_source_mgr mSourceMgr;
+ struct jpeg_progress_mgr mProgressMgr;
+ decoder_error_mgr mErr;
+ jstate mState;
+
+ uint32_t mBytesToSkip;
+
+ const JOCTET* mSegment; // The current segment we are decoding from
+ uint32_t mSegmentLen; // amount of data in mSegment
+
+ JOCTET* mBackBuffer;
+ uint32_t mBackBufferLen; // Offset of end of active backtrack data
+ uint32_t mBackBufferSize; // size in bytes what mBackBuffer was created with
+ uint32_t mBackBufferUnreadLen; // amount of data currently in mBackBuffer
+
+ JOCTET* mProfile;
+ uint32_t mProfileLength;
+
+ uint32_t* mCMSLine;
+
+ bool mReading;
+
+ const Decoder::DecodeStyle mDecodeStyle;
+
+ SurfacePipe mPipe;
+};
+
+} // namespace mozilla::image
+
+#endif // mozilla_image_decoders_nsJPEGDecoder_h
diff --git a/image/decoders/nsJXLDecoder.cpp b/image/decoders/nsJXLDecoder.cpp
new file mode 100644
index 0000000000..b3610f9075
--- /dev/null
+++ b/image/decoders/nsJXLDecoder.cpp
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageLogging.h" // Must appear first
+#include "gfxPlatform.h"
+#include "jxl/codestream_header.h"
+#include "jxl/decode_cxx.h"
+#include "jxl/types.h"
+#include "mozilla/TelemetryHistogramEnums.h"
+#include "mozilla/gfx/Point.h"
+#include "nsJXLDecoder.h"
+
+#include "RasterImage.h"
+#include "SurfacePipeFactory.h"
+
+using namespace mozilla::gfx;
+
+namespace mozilla::image {
+
+#define JXL_TRY(expr) \
+ do { \
+ JxlDecoderStatus _status = (expr); \
+ if (_status != JXL_DEC_SUCCESS) { \
+ return Transition::TerminateFailure(); \
+ } \
+ } while (0);
+
+#define JXL_TRY_BOOL(expr) \
+ do { \
+ bool succeeded = (expr); \
+ if (!succeeded) { \
+ return Transition::TerminateFailure(); \
+ } \
+ } while (0);
+
+static LazyLogModule sJXLLog("JXLDecoder");
+
+nsJXLDecoder::nsJXLDecoder(RasterImage* aImage)
+ : Decoder(aImage),
+ mLexer(Transition::ToUnbuffered(State::FINISHED_JXL_DATA, State::JXL_DATA,
+ SIZE_MAX),
+ Transition::TerminateSuccess()),
+ mDecoder(JxlDecoderMake(nullptr)),
+ mParallelRunner(
+ JxlThreadParallelRunnerMake(nullptr, PreferredThreadCount())) {
+ JxlDecoderSubscribeEvents(mDecoder.get(),
+ JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE);
+ JxlDecoderSetParallelRunner(mDecoder.get(), JxlThreadParallelRunner,
+ mParallelRunner.get());
+
+ MOZ_LOG(sJXLLog, LogLevel::Debug,
+ ("[this=%p] nsJXLDecoder::nsJXLDecoder", this));
+}
+
+nsJXLDecoder::~nsJXLDecoder() {
+ MOZ_LOG(sJXLLog, LogLevel::Debug,
+ ("[this=%p] nsJXLDecoder::~nsJXLDecoder", this));
+}
+
+size_t nsJXLDecoder::PreferredThreadCount() {
+ if (IsMetadataDecode()) {
+ return 0; // no additional worker thread
+ }
+ return JxlThreadParallelRunnerDefaultNumWorkerThreads();
+}
+
+LexerResult nsJXLDecoder::DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) {
+ // return LexerResult(TerminalState::FAILURE);
+ MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
+
+ return mLexer.Lex(aIterator, aOnResume,
+ [=](State aState, const char* aData, size_t aLength) {
+ switch (aState) {
+ case State::JXL_DATA:
+ return ReadJXLData(aData, aLength);
+ case State::FINISHED_JXL_DATA:
+ return FinishedJXLData();
+ }
+ MOZ_CRASH("Unknown State");
+ });
+};
+
+LexerTransition<nsJXLDecoder::State> nsJXLDecoder::ReadJXLData(
+ const char* aData, size_t aLength) {
+ const uint8_t* input = (const uint8_t*)aData;
+ size_t length = aLength;
+ if (mBuffer.length() != 0) {
+ JXL_TRY_BOOL(mBuffer.append(aData, aLength));
+ input = mBuffer.begin();
+ length = mBuffer.length();
+ }
+ JXL_TRY(JxlDecoderSetInput(mDecoder.get(), input, length));
+
+ while (true) {
+ JxlDecoderStatus status = JxlDecoderProcessInput(mDecoder.get());
+ switch (status) {
+ case JXL_DEC_ERROR:
+ default:
+ return Transition::TerminateFailure();
+
+ case JXL_DEC_NEED_MORE_INPUT: {
+ size_t remaining = JxlDecoderReleaseInput(mDecoder.get());
+ mBuffer.clear();
+ JXL_TRY_BOOL(mBuffer.append(aData + aLength - remaining, remaining));
+ return Transition::ContinueUnbuffered(State::JXL_DATA);
+ }
+
+ case JXL_DEC_BASIC_INFO: {
+ JXL_TRY(JxlDecoderGetBasicInfo(mDecoder.get(), &mInfo));
+ PostSize(mInfo.xsize, mInfo.ysize);
+ if (mInfo.alpha_bits > 0) {
+ PostHasTransparency();
+ }
+ if (IsMetadataDecode()) {
+ return Transition::TerminateSuccess();
+ }
+ break;
+ }
+
+ case JXL_DEC_NEED_IMAGE_OUT_BUFFER: {
+ size_t size = 0;
+ JxlPixelFormat format{4, JXL_TYPE_UINT8, JXL_LITTLE_ENDIAN, 0};
+ JXL_TRY(JxlDecoderImageOutBufferSize(mDecoder.get(), &format, &size));
+
+ mOutBuffer.clear();
+ JXL_TRY_BOOL(mOutBuffer.growBy(size));
+ JXL_TRY(JxlDecoderSetImageOutBuffer(mDecoder.get(), &format,
+ mOutBuffer.begin(), size));
+ break;
+ }
+
+ case JXL_DEC_FULL_IMAGE: {
+ OrientedIntSize size(mInfo.xsize, mInfo.ysize);
+ Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
+ this, size, OutputSize(), FullFrame(), SurfaceFormat::R8G8B8A8,
+ SurfaceFormat::OS_RGBA, Nothing(), nullptr, SurfacePipeFlags());
+ for (uint8_t* rowPtr = mOutBuffer.begin(); rowPtr < mOutBuffer.end();
+ rowPtr += mInfo.xsize * 4) {
+ pipe->WriteBuffer(reinterpret_cast<uint32_t*>(rowPtr));
+ }
+
+ if (Maybe<SurfaceInvalidRect> invalidRect = pipe->TakeInvalidRect()) {
+ PostInvalidation(invalidRect->mInputSpaceRect,
+ Some(invalidRect->mOutputSpaceRect));
+ }
+ PostFrameStop();
+ PostDecodeDone();
+ return Transition::TerminateSuccess();
+ }
+ }
+ }
+}
+
+LexerTransition<nsJXLDecoder::State> nsJXLDecoder::FinishedJXLData() {
+ MOZ_ASSERT_UNREACHABLE("Read the entire address space?");
+ return Transition::TerminateFailure();
+}
+
+} // namespace mozilla::image
diff --git a/image/decoders/nsJXLDecoder.h b/image/decoders/nsJXLDecoder.h
new file mode 100644
index 0000000000..6cde7456ca
--- /dev/null
+++ b/image/decoders/nsJXLDecoder.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_nsJXLDecoder_h
+#define mozilla_image_decoders_nsJXLDecoder_h
+
+#include "Decoder.h"
+#include "mp4parse.h"
+#include "SurfacePipe.h"
+
+#include "jxl/decode_cxx.h"
+#include "jxl/thread_parallel_runner_cxx.h"
+
+#include "mozilla/Telemetry.h"
+
+namespace mozilla::image {
+class RasterImage;
+
+class nsJXLDecoder final : public Decoder {
+ public:
+ virtual ~nsJXLDecoder();
+
+ DecoderType GetType() const override { return DecoderType::JXL; }
+
+ protected:
+ LexerResult DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) override;
+
+ private:
+ friend class DecoderFactory;
+
+ // Decoders should only be instantiated via DecoderFactory.
+ explicit nsJXLDecoder(RasterImage* aImage);
+
+ size_t PreferredThreadCount();
+
+ enum class State { JXL_DATA, FINISHED_JXL_DATA };
+
+ LexerTransition<State> ReadJXLData(const char* aData, size_t aLength);
+ LexerTransition<State> FinishedJXLData();
+
+ StreamingLexer<State> mLexer;
+ JxlDecoderPtr mDecoder;
+ JxlThreadParallelRunnerPtr mParallelRunner;
+ Vector<uint8_t> mBuffer;
+ Vector<uint8_t> mOutBuffer;
+ JxlBasicInfo mInfo{};
+};
+
+} // namespace mozilla::image
+
+#endif // mozilla_image_decoders_nsJXLDecoder_h
diff --git a/image/decoders/nsPNGDecoder.cpp b/image/decoders/nsPNGDecoder.cpp
new file mode 100644
index 0000000000..afc2762515
--- /dev/null
+++ b/image/decoders/nsPNGDecoder.cpp
@@ -0,0 +1,1035 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageLogging.h" // Must appear first
+#include "nsPNGDecoder.h"
+
+#include <algorithm>
+#include <cstdint>
+
+#include "gfxColor.h"
+#include "gfxPlatform.h"
+#include "imgFrame.h"
+#include "nsColor.h"
+#include "nsRect.h"
+#include "nspr.h"
+#include "png.h"
+
+#include "RasterImage.h"
+#include "SurfaceCache.h"
+#include "SurfacePipeFactory.h"
+#include "mozilla/DebugOnly.h"
+#include "mozilla/Telemetry.h"
+
+using namespace mozilla::gfx;
+
+using std::min;
+
+namespace mozilla {
+namespace image {
+
+static LazyLogModule sPNGLog("PNGDecoder");
+static LazyLogModule sPNGDecoderAccountingLog("PNGDecoderAccounting");
+
+// limit image dimensions (bug #251381, #591822, #967656, and #1283961)
+#ifndef MOZ_PNG_MAX_WIDTH
+# define MOZ_PNG_MAX_WIDTH 0x7fffffff // Unlimited
+#endif
+#ifndef MOZ_PNG_MAX_HEIGHT
+# define MOZ_PNG_MAX_HEIGHT 0x7fffffff // Unlimited
+#endif
+
+/* Controls the maximum chunk size configuration for libpng. We set this to a
+ * very large number, 256MB specifically. */
+static constexpr png_alloc_size_t kPngMaxChunkSize = 0x10000000;
+
+nsPNGDecoder::AnimFrameInfo::AnimFrameInfo()
+ : mDispose(DisposalMethod::KEEP), mBlend(BlendMethod::OVER), mTimeout(0) {}
+
+#ifdef PNG_APNG_SUPPORTED
+
+int32_t GetNextFrameDelay(png_structp aPNG, png_infop aInfo) {
+ // Delay, in seconds, is delayNum / delayDen.
+ png_uint_16 delayNum = png_get_next_frame_delay_num(aPNG, aInfo);
+ png_uint_16 delayDen = png_get_next_frame_delay_den(aPNG, aInfo);
+
+ if (delayNum == 0) {
+ return 0; // SetFrameTimeout() will set to a minimum.
+ }
+
+ if (delayDen == 0) {
+ delayDen = 100; // So says the APNG spec.
+ }
+
+ // Need to cast delay_num to float to have a proper division and
+ // the result to int to avoid a compiler warning.
+ return static_cast<int32_t>(static_cast<double>(delayNum) * 1000 / delayDen);
+}
+
+nsPNGDecoder::AnimFrameInfo::AnimFrameInfo(png_structp aPNG, png_infop aInfo)
+ : mDispose(DisposalMethod::KEEP), mBlend(BlendMethod::OVER), mTimeout(0) {
+ png_byte dispose_op = png_get_next_frame_dispose_op(aPNG, aInfo);
+ png_byte blend_op = png_get_next_frame_blend_op(aPNG, aInfo);
+
+ if (dispose_op == PNG_DISPOSE_OP_PREVIOUS) {
+ mDispose = DisposalMethod::RESTORE_PREVIOUS;
+ } else if (dispose_op == PNG_DISPOSE_OP_BACKGROUND) {
+ mDispose = DisposalMethod::CLEAR;
+ } else {
+ mDispose = DisposalMethod::KEEP;
+ }
+
+ if (blend_op == PNG_BLEND_OP_SOURCE) {
+ mBlend = BlendMethod::SOURCE;
+ } else {
+ mBlend = BlendMethod::OVER;
+ }
+
+ mTimeout = GetNextFrameDelay(aPNG, aInfo);
+}
+#endif
+
+// First 8 bytes of a PNG file
+const uint8_t nsPNGDecoder::pngSignatureBytes[] = {137, 80, 78, 71,
+ 13, 10, 26, 10};
+
+nsPNGDecoder::nsPNGDecoder(RasterImage* aImage)
+ : Decoder(aImage),
+ mLexer(Transition::ToUnbuffered(State::FINISHED_PNG_DATA, State::PNG_DATA,
+ SIZE_MAX),
+ Transition::TerminateSuccess()),
+ mNextTransition(Transition::ContinueUnbuffered(State::PNG_DATA)),
+ mLastChunkLength(0),
+ mPNG(nullptr),
+ mInfo(nullptr),
+ mCMSLine(nullptr),
+ interlacebuf(nullptr),
+ mFormat(SurfaceFormat::UNKNOWN),
+ mChannels(0),
+ mPass(0),
+ mFrameIsHidden(false),
+ mDisablePremultipliedAlpha(false),
+ mGotInfoCallback(false),
+ mUsePipeTransform(false),
+ mNumFrames(0) {}
+
+nsPNGDecoder::~nsPNGDecoder() {
+ if (mPNG) {
+ png_destroy_read_struct(&mPNG, mInfo ? &mInfo : nullptr, nullptr);
+ }
+ if (mCMSLine) {
+ free(mCMSLine);
+ }
+ if (interlacebuf) {
+ free(interlacebuf);
+ }
+}
+
+nsPNGDecoder::TransparencyType nsPNGDecoder::GetTransparencyType(
+ const OrientedIntRect& aFrameRect) {
+ // Check if the image has a transparent color in its palette.
+ if (HasAlphaChannel()) {
+ return TransparencyType::eAlpha;
+ }
+ if (!aFrameRect.IsEqualEdges(FullFrame())) {
+ MOZ_ASSERT(HasAnimation());
+ return TransparencyType::eFrameRect;
+ }
+
+ return TransparencyType::eNone;
+}
+
+void nsPNGDecoder::PostHasTransparencyIfNeeded(
+ TransparencyType aTransparencyType) {
+ switch (aTransparencyType) {
+ case TransparencyType::eNone:
+ return;
+
+ case TransparencyType::eAlpha:
+ PostHasTransparency();
+ return;
+
+ case TransparencyType::eFrameRect:
+ // If the first frame of animated image doesn't draw into the whole image,
+ // then record that it is transparent. For subsequent frames, this doesn't
+ // affect transparency, because they're composited on top of all previous
+ // frames.
+ if (mNumFrames == 0) {
+ PostHasTransparency();
+ }
+ return;
+ }
+}
+
+// CreateFrame() is used for both simple and animated images.
+nsresult nsPNGDecoder::CreateFrame(const FrameInfo& aFrameInfo) {
+ MOZ_ASSERT(HasSize());
+ MOZ_ASSERT(!IsMetadataDecode());
+
+ // Check if we have transparency, and send notifications if needed.
+ auto transparency = GetTransparencyType(aFrameInfo.mFrameRect);
+ PostHasTransparencyIfNeeded(transparency);
+ mFormat = transparency == TransparencyType::eNone ? SurfaceFormat::OS_RGBX
+ : SurfaceFormat::OS_RGBA;
+
+ // Make sure there's no animation or padding if we're downscaling.
+ MOZ_ASSERT_IF(Size() != OutputSize(), mNumFrames == 0);
+ MOZ_ASSERT_IF(Size() != OutputSize(), !GetImageMetadata().HasAnimation());
+ MOZ_ASSERT_IF(Size() != OutputSize(),
+ transparency != TransparencyType::eFrameRect);
+
+ Maybe<AnimationParams> animParams;
+#ifdef PNG_APNG_SUPPORTED
+ if (!IsFirstFrameDecode() && png_get_valid(mPNG, mInfo, PNG_INFO_acTL)) {
+ mAnimInfo = AnimFrameInfo(mPNG, mInfo);
+
+ if (mAnimInfo.mDispose == DisposalMethod::CLEAR) {
+ // We may have to display the background under this image during
+ // animation playback, so we regard it as transparent.
+ PostHasTransparency();
+ }
+
+ animParams.emplace(
+ AnimationParams{aFrameInfo.mFrameRect.ToUnknownRect(),
+ FrameTimeout::FromRawMilliseconds(mAnimInfo.mTimeout),
+ mNumFrames, mAnimInfo.mBlend, mAnimInfo.mDispose});
+ }
+#endif
+
+ // If this image is interlaced, we can display better quality intermediate
+ // results to the user by post processing them with ADAM7InterpolatingFilter.
+ SurfacePipeFlags pipeFlags = aFrameInfo.mIsInterlaced
+ ? SurfacePipeFlags::ADAM7_INTERPOLATE
+ : SurfacePipeFlags();
+
+ if (mNumFrames == 0) {
+ // The first frame may be displayed progressively.
+ pipeFlags |= SurfacePipeFlags::PROGRESSIVE_DISPLAY;
+ }
+
+ SurfaceFormat inFormat;
+ if (mTransform && !mUsePipeTransform) {
+ // QCMS will output in the correct format.
+ inFormat = mFormat;
+ } else if (transparency == TransparencyType::eAlpha) {
+ // We are outputting directly as RGBA, so we need to swap at this step.
+ inFormat = SurfaceFormat::R8G8B8A8;
+ } else {
+ // We have no alpha channel, so we need to unpack from RGB to BGRA.
+ inFormat = SurfaceFormat::R8G8B8;
+ }
+
+ // Only apply premultiplication if the frame has true alpha. If we ever
+ // support downscaling animated images, we will need to premultiply for frame
+ // rect transparency when downscaling as well.
+ if (transparency == TransparencyType::eAlpha && !mDisablePremultipliedAlpha) {
+ pipeFlags |= SurfacePipeFlags::PREMULTIPLY_ALPHA;
+ }
+
+ qcms_transform* pipeTransform = mUsePipeTransform ? mTransform : nullptr;
+ Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
+ this, Size(), OutputSize(), aFrameInfo.mFrameRect, inFormat, mFormat,
+ animParams, pipeTransform, pipeFlags);
+
+ if (!pipe) {
+ mPipe = SurfacePipe();
+ return NS_ERROR_FAILURE;
+ }
+
+ mPipe = std::move(*pipe);
+
+ mFrameRect = aFrameInfo.mFrameRect;
+ mPass = 0;
+
+ MOZ_LOG(sPNGDecoderAccountingLog, LogLevel::Debug,
+ ("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created "
+ "image frame with %dx%d pixels for decoder %p",
+ mFrameRect.Width(), mFrameRect.Height(), this));
+
+ return NS_OK;
+}
+
+// set timeout and frame disposal method for the current frame
+void nsPNGDecoder::EndImageFrame() {
+ if (mFrameIsHidden) {
+ return;
+ }
+
+ mNumFrames++;
+
+ Opacity opacity = mFormat == SurfaceFormat::OS_RGBX
+ ? Opacity::FULLY_OPAQUE
+ : Opacity::SOME_TRANSPARENCY;
+
+ PostFrameStop(opacity);
+}
+
+nsresult nsPNGDecoder::InitInternal() {
+ mDisablePremultipliedAlpha =
+ bool(GetSurfaceFlags() & SurfaceFlags::NO_PREMULTIPLY_ALPHA);
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ static png_byte color_chunks[] = {99, 72, 82, 77, '\0', // cHRM
+ 105, 67, 67, 80, '\0'}; // iCCP
+ static png_byte unused_chunks[] = {98, 75, 71, 68, '\0', // bKGD
+ 101, 88, 73, 102, '\0', // eXIf
+ 104, 73, 83, 84, '\0', // hIST
+ 105, 84, 88, 116, '\0', // iTXt
+ 111, 70, 70, 115, '\0', // oFFs
+ 112, 67, 65, 76, '\0', // pCAL
+ 115, 67, 65, 76, '\0', // sCAL
+ 112, 72, 89, 115, '\0', // pHYs
+ 115, 66, 73, 84, '\0', // sBIT
+ 115, 80, 76, 84, '\0', // sPLT
+ 116, 69, 88, 116, '\0', // tEXt
+ 116, 73, 77, 69, '\0', // tIME
+ 122, 84, 88, 116, '\0'}; // zTXt
+#endif
+
+ // Initialize the container's source image header
+ // Always decode to 24 bit pixdepth
+
+ mPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr,
+ nsPNGDecoder::error_callback,
+ nsPNGDecoder::warning_callback);
+ if (!mPNG) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ mInfo = png_create_info_struct(mPNG);
+ if (!mInfo) {
+ png_destroy_read_struct(&mPNG, nullptr, nullptr);
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ // Ignore unused chunks
+ if (mCMSMode == CMSMode::Off || IsMetadataDecode()) {
+ png_set_keep_unknown_chunks(mPNG, 1, color_chunks, 2);
+ }
+
+ png_set_keep_unknown_chunks(mPNG, 1, unused_chunks,
+ (int)sizeof(unused_chunks) / 5);
+#endif
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ png_set_user_limits(mPNG, MOZ_PNG_MAX_WIDTH, MOZ_PNG_MAX_HEIGHT);
+ png_set_chunk_malloc_max(mPNG, kPngMaxChunkSize);
+#endif
+
+#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ // Disallow palette-index checking, for speed; we would ignore the warning
+ // anyhow. This feature was added at libpng version 1.5.10 and is disabled
+ // in the embedded libpng but enabled by default in the system libpng. This
+ // call also disables it in the system libpng, for decoding speed.
+ // Bug #745202.
+ png_set_check_for_invalid_index(mPNG, 0);
+#endif
+
+#ifdef PNG_SET_OPTION_SUPPORTED
+# if defined(PNG_sRGB_PROFILE_CHECKS) && PNG_sRGB_PROFILE_CHECKS >= 0
+ // Skip checking of sRGB ICC profiles
+ png_set_option(mPNG, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON);
+# endif
+
+# ifdef PNG_MAXIMUM_INFLATE_WINDOW
+ // Force a larger zlib inflate window as some images in the wild have
+ // incorrectly set metadata (specifically CMF bits) which prevent us from
+ // decoding them otherwise.
+ png_set_option(mPNG, PNG_MAXIMUM_INFLATE_WINDOW, PNG_OPTION_ON);
+# endif
+#endif
+
+ // use this as libpng "progressive pointer" (retrieve in callbacks)
+ png_set_progressive_read_fn(
+ mPNG, static_cast<png_voidp>(this), nsPNGDecoder::info_callback,
+ nsPNGDecoder::row_callback, nsPNGDecoder::end_callback);
+
+ return NS_OK;
+}
+
+LexerResult nsPNGDecoder::DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) {
+ MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
+
+ return mLexer.Lex(aIterator, aOnResume,
+ [=](State aState, const char* aData, size_t aLength) {
+ switch (aState) {
+ case State::PNG_DATA:
+ return ReadPNGData(aData, aLength);
+ case State::FINISHED_PNG_DATA:
+ return FinishedPNGData();
+ }
+ MOZ_CRASH("Unknown State");
+ });
+}
+
+LexerTransition<nsPNGDecoder::State> nsPNGDecoder::ReadPNGData(
+ const char* aData, size_t aLength) {
+ // If we were waiting until after returning from a yield to call
+ // CreateFrame(), call it now.
+ if (mNextFrameInfo) {
+ if (NS_FAILED(CreateFrame(*mNextFrameInfo))) {
+ return Transition::TerminateFailure();
+ }
+
+ MOZ_ASSERT(mImageData, "Should have a buffer now");
+ mNextFrameInfo = Nothing();
+ }
+
+ // libpng uses setjmp/longjmp for error handling.
+ if (setjmp(png_jmpbuf(mPNG))) {
+ return Transition::TerminateFailure();
+ }
+
+ // Pass the data off to libpng.
+ mLastChunkLength = aLength;
+ mNextTransition = Transition::ContinueUnbuffered(State::PNG_DATA);
+ png_process_data(mPNG, mInfo,
+ reinterpret_cast<unsigned char*>(const_cast<char*>((aData))),
+ aLength);
+
+ // Make sure that we've reached a terminal state if decoding is done.
+ MOZ_ASSERT_IF(GetDecodeDone(), mNextTransition.NextStateIsTerminal());
+ MOZ_ASSERT_IF(HasError(), mNextTransition.NextStateIsTerminal());
+
+ // Continue with whatever transition the callback code requested. We
+ // initialized this to Transition::ContinueUnbuffered(State::PNG_DATA) above,
+ // so by default we just continue the unbuffered read.
+ return mNextTransition;
+}
+
+LexerTransition<nsPNGDecoder::State> nsPNGDecoder::FinishedPNGData() {
+ // Since we set up an unbuffered read for SIZE_MAX bytes, if we actually read
+ // all that data something is really wrong.
+ MOZ_ASSERT_UNREACHABLE("Read the entire address space?");
+ return Transition::TerminateFailure();
+}
+
+// Sets up gamma pre-correction in libpng before our callback gets called.
+// We need to do this if we don't end up with a CMS profile.
+static void PNGDoGammaCorrection(png_structp png_ptr, png_infop info_ptr) {
+ double aGamma;
+
+ if (png_get_gAMA(png_ptr, info_ptr, &aGamma)) {
+ if ((aGamma <= 0.0) || (aGamma > 21474.83)) {
+ aGamma = 0.45455;
+ png_set_gAMA(png_ptr, info_ptr, aGamma);
+ }
+ png_set_gamma(png_ptr, 2.2, aGamma);
+ } else {
+ png_set_gamma(png_ptr, 2.2, 0.45455);
+ }
+}
+
+// Adapted from http://www.littlecms.com/pngchrm.c example code
+uint32_t nsPNGDecoder::ReadColorProfile(png_structp png_ptr, png_infop info_ptr,
+ int color_type, bool* sRGBTag) {
+ // First try to see if iCCP chunk is present
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP)) {
+ png_uint_32 profileLen;
+ png_bytep profileData;
+ png_charp profileName;
+ int compression;
+
+ png_get_iCCP(png_ptr, info_ptr, &profileName, &compression, &profileData,
+ &profileLen);
+
+ mInProfile = qcms_profile_from_memory((char*)profileData, profileLen);
+ if (mInProfile) {
+ uint32_t profileSpace = qcms_profile_get_color_space(mInProfile);
+
+ bool mismatch = false;
+ if (color_type & PNG_COLOR_MASK_COLOR) {
+ if (profileSpace != icSigRgbData) {
+ mismatch = true;
+ }
+ } else {
+ if (profileSpace == icSigRgbData) {
+ png_set_gray_to_rgb(png_ptr);
+ } else if (profileSpace != icSigGrayData) {
+ mismatch = true;
+ }
+ }
+
+ if (mismatch) {
+ qcms_profile_release(mInProfile);
+ mInProfile = nullptr;
+ } else {
+ return qcms_profile_get_rendering_intent(mInProfile);
+ }
+ }
+ }
+
+ // Check sRGB chunk
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) {
+ *sRGBTag = true;
+
+ int fileIntent;
+ png_set_gray_to_rgb(png_ptr);
+ png_get_sRGB(png_ptr, info_ptr, &fileIntent);
+ uint32_t map[] = {QCMS_INTENT_PERCEPTUAL, QCMS_INTENT_RELATIVE_COLORIMETRIC,
+ QCMS_INTENT_SATURATION,
+ QCMS_INTENT_ABSOLUTE_COLORIMETRIC};
+ return map[fileIntent];
+ }
+
+ // Check gAMA/cHRM chunks
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA) &&
+ png_get_valid(png_ptr, info_ptr, PNG_INFO_cHRM)) {
+ qcms_CIE_xyYTRIPLE primaries;
+ qcms_CIE_xyY whitePoint;
+
+ png_get_cHRM(png_ptr, info_ptr, &whitePoint.x, &whitePoint.y,
+ &primaries.red.x, &primaries.red.y, &primaries.green.x,
+ &primaries.green.y, &primaries.blue.x, &primaries.blue.y);
+ whitePoint.Y = primaries.red.Y = primaries.green.Y = primaries.blue.Y = 1.0;
+
+ double gammaOfFile;
+
+ png_get_gAMA(png_ptr, info_ptr, &gammaOfFile);
+
+ mInProfile = qcms_profile_create_rgb_with_gamma(whitePoint, primaries,
+ 1.0 / gammaOfFile);
+
+ if (mInProfile) {
+ png_set_gray_to_rgb(png_ptr);
+ }
+ }
+
+ return QCMS_INTENT_PERCEPTUAL; // Our default
+}
+
+void nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr) {
+ png_uint_32 width, height;
+ int bit_depth, color_type, interlace_type, compression_type, filter_type;
+ unsigned int channels;
+
+ png_bytep trans = nullptr;
+ int num_trans = 0;
+
+ nsPNGDecoder* decoder =
+ static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
+
+ if (decoder->mGotInfoCallback) {
+ MOZ_LOG(sPNGLog, LogLevel::Warning,
+ ("libpng called info_callback more than once\n"));
+ return;
+ }
+
+ decoder->mGotInfoCallback = true;
+
+ // Always decode to 24-bit RGB or 32-bit RGBA
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
+ &interlace_type, &compression_type, &filter_type);
+
+ const OrientedIntRect frameRect(0, 0, width, height);
+
+ // Post our size to the superclass
+ decoder->PostSize(frameRect.Width(), frameRect.Height());
+
+ if (width > SurfaceCache::MaximumCapacity() / (bit_depth > 8 ? 16 : 8)) {
+ // libpng needs space to allocate two row buffers
+ png_error(decoder->mPNG, "Image is too wide");
+ }
+
+ if (decoder->HasError()) {
+ // Setting the size led to an error.
+ png_error(decoder->mPNG, "Sizing error");
+ }
+
+ if (color_type == PNG_COLOR_TYPE_PALETTE) {
+ png_set_expand(png_ptr);
+ }
+
+ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
+ png_set_expand(png_ptr);
+ }
+
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ png_color_16p trans_values;
+ png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values);
+ // libpng doesn't reject a tRNS chunk with out-of-range samples
+ // so we check it here to avoid setting up a useless opacity
+ // channel or producing unexpected transparent pixels (bug #428045)
+ if (bit_depth < 16) {
+ png_uint_16 sample_max = (1 << bit_depth) - 1;
+ if ((color_type == PNG_COLOR_TYPE_GRAY &&
+ trans_values->gray > sample_max) ||
+ (color_type == PNG_COLOR_TYPE_RGB &&
+ (trans_values->red > sample_max ||
+ trans_values->green > sample_max ||
+ trans_values->blue > sample_max))) {
+ // clear the tRNS valid flag and release tRNS memory
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
+ num_trans = 0;
+ }
+ }
+ if (num_trans != 0) {
+ png_set_expand(png_ptr);
+ }
+ }
+
+ if (bit_depth == 16) {
+ png_set_scale_16(png_ptr);
+ }
+
+ // We only need to extract the color profile for non-metadata decodes. It is
+ // fairly expensive to read the profile and create the transform so we should
+ // avoid it if not necessary.
+ uint32_t intent = -1;
+ bool sRGBTag = false;
+ if (!decoder->IsMetadataDecode()) {
+ if (decoder->mCMSMode != CMSMode::Off) {
+ intent = gfxPlatform::GetRenderingIntent();
+ uint32_t pIntent =
+ decoder->ReadColorProfile(png_ptr, info_ptr, color_type, &sRGBTag);
+ // If we're not mandating an intent, use the one from the image.
+ if (intent == uint32_t(-1)) {
+ intent = pIntent;
+ }
+ }
+ if (!decoder->mInProfile || !decoder->GetCMSOutputProfile()) {
+ png_set_gray_to_rgb(png_ptr);
+
+ // only do gamma correction if CMS isn't entirely disabled
+ if (decoder->mCMSMode != CMSMode::Off) {
+ PNGDoGammaCorrection(png_ptr, info_ptr);
+ }
+ }
+ }
+
+ // Let libpng expand interlaced images.
+ const bool isInterlaced = interlace_type == PNG_INTERLACE_ADAM7;
+ if (isInterlaced) {
+ png_set_interlace_handling(png_ptr);
+ }
+
+ // now all of those things we set above are used to update various struct
+ // members and whatnot, after which we can get channels, rowbytes, etc.
+ png_read_update_info(png_ptr, info_ptr);
+ decoder->mChannels = channels = png_get_channels(png_ptr, info_ptr);
+
+ //---------------------------------------------------------------//
+ // copy PNG info into imagelib structs (formerly png_set_dims()) //
+ //---------------------------------------------------------------//
+
+ if (channels < 1 || channels > 4) {
+ png_error(decoder->mPNG, "Invalid number of channels");
+ }
+
+#ifdef PNG_APNG_SUPPORTED
+ bool isAnimated = png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL);
+ if (isAnimated) {
+ int32_t rawTimeout = GetNextFrameDelay(png_ptr, info_ptr);
+ decoder->PostIsAnimated(FrameTimeout::FromRawMilliseconds(rawTimeout));
+
+ if (decoder->Size() != decoder->OutputSize() &&
+ !decoder->IsFirstFrameDecode()) {
+ MOZ_ASSERT_UNREACHABLE(
+ "Doing downscale-during-decode "
+ "for an animated image?");
+ png_error(decoder->mPNG, "Invalid downscale attempt"); // Abort decode.
+ }
+ }
+#endif
+
+ auto transparency = decoder->GetTransparencyType(frameRect);
+ if (decoder->IsMetadataDecode()) {
+ // If we are animated then the first frame rect is either:
+ // 1) the whole image if the IDAT chunk is part of the animation
+ // 2) the frame rect of the first fDAT chunk otherwise.
+ // If we are not animated then we want to make sure to call
+ // PostHasTransparency in the metadata decode if we need to. So it's
+ // okay to pass IntRect(0, 0, width, height) here for animated images;
+ // they will call with the proper first frame rect in the full decode.
+ decoder->PostHasTransparencyIfNeeded(transparency);
+
+ // We have the metadata we're looking for, so stop here, before we allocate
+ // buffers below.
+ return decoder->DoTerminate(png_ptr, TerminalState::SUCCESS);
+ }
+
+ if (decoder->mInProfile && decoder->GetCMSOutputProfile()) {
+ qcms_data_type inType;
+ qcms_data_type outType;
+
+ uint32_t profileSpace = qcms_profile_get_color_space(decoder->mInProfile);
+ decoder->mUsePipeTransform = profileSpace != icSigGrayData;
+ if (decoder->mUsePipeTransform) {
+ // If the transform happens with SurfacePipe, it will be in RGBA if we
+ // have an alpha channel, because the swizzle and premultiplication
+ // happens after color management. Otherwise it will be in BGRA because
+ // the swizzle happens at the start.
+ if (transparency == TransparencyType::eAlpha) {
+ inType = QCMS_DATA_RGBA_8;
+ outType = QCMS_DATA_RGBA_8;
+ } else {
+ inType = gfxPlatform::GetCMSOSRGBAType();
+ outType = inType;
+ }
+ } else {
+ if (color_type & PNG_COLOR_MASK_ALPHA) {
+ inType = QCMS_DATA_GRAYA_8;
+ outType = gfxPlatform::GetCMSOSRGBAType();
+ } else {
+ inType = QCMS_DATA_GRAY_8;
+ outType = gfxPlatform::GetCMSOSRGBAType();
+ }
+ }
+
+ decoder->mTransform = qcms_transform_create(decoder->mInProfile, inType,
+ decoder->GetCMSOutputProfile(),
+ outType, (qcms_intent)intent);
+ } else if ((sRGBTag && decoder->mCMSMode == CMSMode::TaggedOnly) ||
+ decoder->mCMSMode == CMSMode::All) {
+ // If the transform happens with SurfacePipe, it will be in RGBA if we
+ // have an alpha channel, because the swizzle and premultiplication
+ // happens after color management. Otherwise it will be in OS_RGBA because
+ // the swizzle happens at the start.
+ if (transparency == TransparencyType::eAlpha) {
+ decoder->mTransform =
+ decoder->GetCMSsRGBTransform(SurfaceFormat::R8G8B8A8);
+ } else {
+ decoder->mTransform =
+ decoder->GetCMSsRGBTransform(SurfaceFormat::OS_RGBA);
+ }
+ decoder->mUsePipeTransform = true;
+ }
+
+#ifdef PNG_APNG_SUPPORTED
+ if (isAnimated) {
+ png_set_progressive_frame_fn(png_ptr, nsPNGDecoder::frame_info_callback,
+ nullptr);
+ }
+
+ if (png_get_first_frame_is_hidden(png_ptr, info_ptr)) {
+ decoder->mFrameIsHidden = true;
+ } else {
+#endif
+ nsresult rv = decoder->CreateFrame(FrameInfo{frameRect, isInterlaced});
+ if (NS_FAILED(rv)) {
+ png_error(decoder->mPNG, "CreateFrame failed");
+ }
+ MOZ_ASSERT(decoder->mImageData, "Should have a buffer now");
+#ifdef PNG_APNG_SUPPORTED
+ }
+#endif
+
+ if (decoder->mTransform && !decoder->mUsePipeTransform) {
+ decoder->mCMSLine =
+ static_cast<uint8_t*>(malloc(sizeof(uint32_t) * frameRect.Width()));
+ if (!decoder->mCMSLine) {
+ png_error(decoder->mPNG, "malloc of mCMSLine failed");
+ }
+ }
+
+ if (interlace_type == PNG_INTERLACE_ADAM7) {
+ if (frameRect.Height() <
+ INT32_MAX / (frameRect.Width() * int32_t(channels))) {
+ const size_t bufferSize =
+ channels * frameRect.Width() * frameRect.Height();
+
+ if (bufferSize > SurfaceCache::MaximumCapacity()) {
+ png_error(decoder->mPNG, "Insufficient memory to deinterlace image");
+ }
+
+ decoder->interlacebuf = static_cast<uint8_t*>(malloc(bufferSize));
+ }
+ if (!decoder->interlacebuf) {
+ png_error(decoder->mPNG, "malloc of interlacebuf failed");
+ }
+ }
+}
+
+void nsPNGDecoder::PostInvalidationIfNeeded() {
+ Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect();
+ if (!invalidRect) {
+ return;
+ }
+
+ PostInvalidation(invalidRect->mInputSpaceRect,
+ Some(invalidRect->mOutputSpaceRect));
+}
+
+void nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row,
+ png_uint_32 row_num, int pass) {
+ /* libpng comments:
+ *
+ * This function is called for every row in the image. If the
+ * image is interlacing, and you turned on the interlace handler,
+ * this function will be called for every row in every pass.
+ * Some of these rows will not be changed from the previous pass.
+ * When the row is not changed, the new_row variable will be
+ * nullptr. The rows and passes are called in order, so you don't
+ * really need the row_num and pass, but I'm supplying them
+ * because it may make your life easier.
+ *
+ * For the non-nullptr rows of interlaced images, you must call
+ * png_progressive_combine_row() passing in the row and the
+ * old row. You can call this function for nullptr rows (it will
+ * just return) and for non-interlaced images (it just does the
+ * memcpy for you) if it will make the code easier. Thus, you
+ * can just do this for all cases:
+ *
+ * png_progressive_combine_row(png_ptr, old_row, new_row);
+ *
+ * where old_row is what was displayed for previous rows. Note
+ * that the first pass (pass == 0 really) will completely cover
+ * the old row, so the rows do not have to be initialized. After
+ * the first pass (and only for interlaced images), you will have
+ * to pass the current row, and the function will combine the
+ * old row and the new row.
+ */
+ nsPNGDecoder* decoder =
+ static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
+
+ if (decoder->mFrameIsHidden) {
+ return; // Skip this frame.
+ }
+
+ MOZ_ASSERT_IF(decoder->IsFirstFrameDecode(), decoder->mNumFrames == 0);
+
+ while (pass > decoder->mPass) {
+ // Advance to the next pass. We may have to do this multiple times because
+ // libpng will skip passes if the image is so small that no pixels have
+ // changed on a given pass, but ADAM7InterpolatingFilter needs to be reset
+ // once for every pass to perform interpolation properly.
+ decoder->mPipe.ResetToFirstRow();
+ decoder->mPass++;
+ }
+
+ const png_uint_32 height =
+ static_cast<png_uint_32>(decoder->mFrameRect.Height());
+
+ if (row_num >= height) {
+ // Bail if we receive extra rows. This is especially important because if we
+ // didn't, we might overflow the deinterlacing buffer.
+ MOZ_ASSERT_UNREACHABLE("libpng producing extra rows?");
+ return;
+ }
+
+ // Note that |new_row| may be null here, indicating that this is an interlaced
+ // image and |row_callback| is being called for a row that hasn't changed.
+ MOZ_ASSERT_IF(!new_row, decoder->interlacebuf);
+
+ if (decoder->interlacebuf) {
+ uint32_t width = uint32_t(decoder->mFrameRect.Width());
+
+ // We'll output the deinterlaced version of the row.
+ uint8_t* rowToWrite =
+ decoder->interlacebuf + (row_num * decoder->mChannels * width);
+
+ // Update the deinterlaced version of this row with the new data.
+ png_progressive_combine_row(png_ptr, rowToWrite, new_row);
+
+ decoder->WriteRow(rowToWrite);
+ } else {
+ decoder->WriteRow(new_row);
+ }
+}
+
+void nsPNGDecoder::WriteRow(uint8_t* aRow) {
+ MOZ_ASSERT(aRow);
+
+ uint8_t* rowToWrite = aRow;
+ uint32_t width = uint32_t(mFrameRect.Width());
+
+ // Apply color management to the row, if necessary, before writing it out.
+ // This is only needed for grayscale images.
+ if (mTransform && !mUsePipeTransform) {
+ MOZ_ASSERT(mCMSLine);
+ qcms_transform_data(mTransform, rowToWrite, mCMSLine, width);
+ rowToWrite = mCMSLine;
+ }
+
+ // Write this row to the SurfacePipe.
+ DebugOnly<WriteState> result =
+ mPipe.WriteBuffer(reinterpret_cast<uint32_t*>(rowToWrite));
+ MOZ_ASSERT(WriteState(result) != WriteState::FAILURE);
+
+ PostInvalidationIfNeeded();
+}
+
+void nsPNGDecoder::DoTerminate(png_structp aPNGStruct, TerminalState aState) {
+ // Stop processing data. Note that we intentionally ignore the return value of
+ // png_process_data_pause(), which tells us how many bytes of the data that
+ // was passed to png_process_data() have not been consumed yet, because now
+ // that we've reached a terminal state, we won't do any more decoding or call
+ // back into libpng anymore.
+ png_process_data_pause(aPNGStruct, /* save = */ false);
+
+ mNextTransition = aState == TerminalState::SUCCESS
+ ? Transition::TerminateSuccess()
+ : Transition::TerminateFailure();
+}
+
+void nsPNGDecoder::DoYield(png_structp aPNGStruct) {
+ // Pause data processing. png_process_data_pause() returns how many bytes of
+ // the data that was passed to png_process_data() have not been consumed yet.
+ // We use this information to tell StreamingLexer where to place us in the
+ // input stream when we come back from the yield.
+ png_size_t pendingBytes = png_process_data_pause(aPNGStruct,
+ /* save = */ false);
+
+ MOZ_ASSERT(pendingBytes < mLastChunkLength);
+ size_t consumedBytes = mLastChunkLength - min(pendingBytes, mLastChunkLength);
+
+ mNextTransition =
+ Transition::ContinueUnbufferedAfterYield(State::PNG_DATA, consumedBytes);
+}
+
+nsresult nsPNGDecoder::FinishInternal() {
+ // We shouldn't be called in error cases.
+ MOZ_ASSERT(!HasError(), "Can't call FinishInternal on error!");
+
+ if (IsMetadataDecode()) {
+ return NS_OK;
+ }
+
+ int32_t loop_count = 0;
+#ifdef PNG_APNG_SUPPORTED
+ if (png_get_valid(mPNG, mInfo, PNG_INFO_acTL)) {
+ int32_t num_plays = png_get_num_plays(mPNG, mInfo);
+ loop_count = num_plays - 1;
+ }
+#endif
+
+ if (InFrame()) {
+ EndImageFrame();
+ }
+ PostDecodeDone(loop_count);
+
+ return NS_OK;
+}
+
+#ifdef PNG_APNG_SUPPORTED
+// got the header of a new frame that's coming
+void nsPNGDecoder::frame_info_callback(png_structp png_ptr,
+ png_uint_32 frame_num) {
+ nsPNGDecoder* decoder =
+ static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
+
+ // old frame is done
+ decoder->EndImageFrame();
+
+ const bool previousFrameWasHidden = decoder->mFrameIsHidden;
+
+ if (!previousFrameWasHidden && decoder->IsFirstFrameDecode()) {
+ // We're about to get a second non-hidden frame, but we only want the first.
+ // Stop decoding now. (And avoid allocating the unnecessary buffers below.)
+ return decoder->DoTerminate(png_ptr, TerminalState::SUCCESS);
+ }
+
+ // Only the first frame can be hidden, so unhide unconditionally here.
+ decoder->mFrameIsHidden = false;
+
+ // Save the information necessary to create the frame; we'll actually create
+ // it when we return from the yield.
+ const OrientedIntRect frameRect(
+ png_get_next_frame_x_offset(png_ptr, decoder->mInfo),
+ png_get_next_frame_y_offset(png_ptr, decoder->mInfo),
+ png_get_next_frame_width(png_ptr, decoder->mInfo),
+ png_get_next_frame_height(png_ptr, decoder->mInfo));
+ const bool isInterlaced = bool(decoder->interlacebuf);
+
+# ifndef MOZ_EMBEDDED_LIBPNG
+ // if using system library, check frame_width and height against 0
+ if (frameRect.width == 0) {
+ png_error(png_ptr, "Frame width must not be 0");
+ }
+ if (frameRect.height == 0) {
+ png_error(png_ptr, "Frame height must not be 0");
+ }
+# endif
+
+ const FrameInfo info{frameRect, isInterlaced};
+
+ // If the previous frame was hidden, skip the yield (which will mislead the
+ // caller, who will think the previous frame was real) and just allocate the
+ // new frame here.
+ if (previousFrameWasHidden) {
+ if (NS_FAILED(decoder->CreateFrame(info))) {
+ return decoder->DoTerminate(png_ptr, TerminalState::FAILURE);
+ }
+
+ MOZ_ASSERT(decoder->mImageData, "Should have a buffer now");
+ return; // No yield, so we'll just keep decoding.
+ }
+
+ // Yield to the caller to notify them that the previous frame is now complete.
+ decoder->mNextFrameInfo = Some(info);
+ return decoder->DoYield(png_ptr);
+}
+#endif
+
+void nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr) {
+ /* libpng comments:
+ *
+ * this function is called when the whole image has been read,
+ * including any chunks after the image (up to and including
+ * the IEND). You will usually have the same info chunk as you
+ * had in the header, although some data may have been added
+ * to the comments and time fields.
+ *
+ * Most people won't do much here, perhaps setting a flag that
+ * marks the image as finished.
+ */
+
+ nsPNGDecoder* decoder =
+ static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
+
+ // We shouldn't get here if we've hit an error
+ MOZ_ASSERT(!decoder->HasError(), "Finishing up PNG but hit error!");
+
+ return decoder->DoTerminate(png_ptr, TerminalState::SUCCESS);
+}
+
+void nsPNGDecoder::error_callback(png_structp png_ptr,
+ png_const_charp error_msg) {
+ MOZ_LOG(sPNGLog, LogLevel::Error, ("libpng error: %s\n", error_msg));
+ png_longjmp(png_ptr, 1);
+}
+
+void nsPNGDecoder::warning_callback(png_structp png_ptr,
+ png_const_charp warning_msg) {
+ MOZ_LOG(sPNGLog, LogLevel::Warning, ("libpng warning: %s\n", warning_msg));
+}
+
+Maybe<Telemetry::HistogramID> nsPNGDecoder::SpeedHistogram() const {
+ return Some(Telemetry::IMAGE_DECODE_SPEED_PNG);
+}
+
+bool nsPNGDecoder::IsValidICOResource() const {
+ // Only 32-bit RGBA PNGs are valid ICO resources; see here:
+ // http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx
+
+ // If there are errors in the call to png_get_IHDR, the error_callback in
+ // nsPNGDecoder.cpp is called. In this error callback we do a longjmp, so
+ // we need to save the jump buffer here. Otherwise we'll end up without a
+ // proper callstack.
+ if (setjmp(png_jmpbuf(mPNG))) {
+ // We got here from a longjmp call indirectly from png_get_IHDR
+ return false;
+ }
+
+ png_uint_32 png_width, // Unused
+ png_height; // Unused
+
+ int png_bit_depth, png_color_type;
+
+ if (png_get_IHDR(mPNG, mInfo, &png_width, &png_height, &png_bit_depth,
+ &png_color_type, nullptr, nullptr, nullptr)) {
+ return ((png_color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ png_color_type == PNG_COLOR_TYPE_RGB) &&
+ png_bit_depth == 8);
+ } else {
+ return false;
+ }
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/decoders/nsPNGDecoder.h b/image/decoders/nsPNGDecoder.h
new file mode 100644
index 0000000000..89d66fa5eb
--- /dev/null
+++ b/image/decoders/nsPNGDecoder.h
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_nsPNGDecoder_h
+#define mozilla_image_decoders_nsPNGDecoder_h
+
+#include "Decoder.h"
+#include "png.h"
+#include "StreamingLexer.h"
+#include "SurfacePipe.h"
+#include "mozilla/gfx/Swizzle.h"
+
+namespace mozilla {
+namespace image {
+class RasterImage;
+
+class nsPNGDecoder : public Decoder {
+ public:
+ virtual ~nsPNGDecoder();
+
+ /// @return true if this PNG is a valid ICO resource.
+ bool IsValidICOResource() const override;
+
+ DecoderType GetType() const override { return DecoderType::PNG; }
+
+ protected:
+ nsresult InitInternal() override;
+ nsresult FinishInternal() override;
+ LexerResult DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) override;
+
+ Maybe<Telemetry::HistogramID> SpeedHistogram() const override;
+
+ private:
+ friend class DecoderFactory;
+
+ // Decoders should only be instantiated via DecoderFactory.
+ explicit nsPNGDecoder(RasterImage* aImage);
+
+ /// The information necessary to create a frame.
+ struct FrameInfo {
+ OrientedIntRect mFrameRect;
+ bool mIsInterlaced;
+ };
+
+ nsresult CreateFrame(const FrameInfo& aFrameInfo);
+ void EndImageFrame();
+
+ uint32_t ReadColorProfile(png_structp png_ptr, png_infop info_ptr,
+ int color_type, bool* sRGBTag);
+
+ bool HasAlphaChannel() const { return mChannels == 2 || mChannels == 4; }
+
+ enum class TransparencyType { eNone, eAlpha, eFrameRect };
+
+ TransparencyType GetTransparencyType(const OrientedIntRect& aFrameRect);
+ void PostHasTransparencyIfNeeded(TransparencyType aTransparencyType);
+
+ void PostInvalidationIfNeeded();
+
+ void WriteRow(uint8_t* aRow);
+
+ // Convenience methods to make interacting with StreamingLexer from inside
+ // a libpng callback easier.
+ void DoTerminate(png_structp aPNGStruct, TerminalState aState);
+ void DoYield(png_structp aPNGStruct);
+
+ enum class State { PNG_DATA, FINISHED_PNG_DATA };
+
+ LexerTransition<State> ReadPNGData(const char* aData, size_t aLength);
+ LexerTransition<State> FinishedPNGData();
+
+ StreamingLexer<State> mLexer;
+
+ // The next lexer state transition. We need to store it here because we can't
+ // directly return arbitrary values from libpng callbacks.
+ LexerTransition<State> mNextTransition;
+
+ // We yield to the caller every time we finish decoding a frame. When this
+ // happens, we need to allocate the next frame after returning from the yield.
+ // |mNextFrameInfo| is used to store the information needed to allocate the
+ // next frame.
+ Maybe<FrameInfo> mNextFrameInfo;
+
+ // The length of the last chunk of data passed to ReadPNGData(). We use this
+ // to arrange to arrive back at the correct spot in the data after yielding.
+ size_t mLastChunkLength;
+
+ public:
+ png_structp mPNG;
+ png_infop mInfo;
+ OrientedIntRect mFrameRect;
+ uint8_t* mCMSLine;
+ uint8_t* interlacebuf;
+ gfx::SurfaceFormat mFormat;
+
+ uint8_t mChannels;
+ uint8_t mPass;
+ bool mFrameIsHidden;
+ bool mDisablePremultipliedAlpha;
+ bool mGotInfoCallback;
+ bool mUsePipeTransform;
+
+ struct AnimFrameInfo {
+ AnimFrameInfo();
+#ifdef PNG_APNG_SUPPORTED
+ AnimFrameInfo(png_structp aPNG, png_infop aInfo);
+#endif
+
+ DisposalMethod mDispose;
+ BlendMethod mBlend;
+ int32_t mTimeout;
+ };
+
+ AnimFrameInfo mAnimInfo;
+
+ SurfacePipe mPipe; /// The SurfacePipe used to write to the output surface.
+
+ // The number of frames we've finished.
+ uint32_t mNumFrames;
+
+ // libpng callbacks
+ // We put these in the class so that they can access protected members.
+ static void PNGAPI info_callback(png_structp png_ptr, png_infop info_ptr);
+ static void PNGAPI row_callback(png_structp png_ptr, png_bytep new_row,
+ png_uint_32 row_num, int pass);
+#ifdef PNG_APNG_SUPPORTED
+ static void PNGAPI frame_info_callback(png_structp png_ptr,
+ png_uint_32 frame_num);
+#endif
+ static void PNGAPI end_callback(png_structp png_ptr, png_infop info_ptr);
+ static void PNGAPI error_callback(png_structp png_ptr,
+ png_const_charp error_msg);
+ static void PNGAPI warning_callback(png_structp png_ptr,
+ png_const_charp warning_msg);
+
+ // This is defined in the PNG spec as an invariant. We use it to
+ // do manual validation without libpng.
+ static const uint8_t pngSignatureBytes[];
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_decoders_nsPNGDecoder_h
diff --git a/image/decoders/nsWebPDecoder.cpp b/image/decoders/nsWebPDecoder.cpp
new file mode 100644
index 0000000000..e7467f0066
--- /dev/null
+++ b/image/decoders/nsWebPDecoder.cpp
@@ -0,0 +1,605 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageLogging.h" // Must appear first
+#include "gfxPlatform.h"
+#include "mozilla/TelemetryHistogramEnums.h"
+#include "nsWebPDecoder.h"
+
+#include "RasterImage.h"
+#include "SurfacePipeFactory.h"
+
+using namespace mozilla::gfx;
+
+namespace mozilla {
+namespace image {
+
+static LazyLogModule sWebPLog("WebPDecoder");
+
+nsWebPDecoder::nsWebPDecoder(RasterImage* aImage)
+ : Decoder(aImage),
+ mDecoder(nullptr),
+ mBlend(BlendMethod::OVER),
+ mDisposal(DisposalMethod::KEEP),
+ mTimeout(FrameTimeout::Forever()),
+ mFormat(SurfaceFormat::OS_RGBX),
+ mLastRow(0),
+ mCurrentFrame(0),
+ mData(nullptr),
+ mLength(0),
+ mIteratorComplete(false),
+ mNeedDemuxer(true),
+ mGotColorProfile(false) {
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::nsWebPDecoder", this));
+}
+
+nsWebPDecoder::~nsWebPDecoder() {
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::~nsWebPDecoder", this));
+ if (mDecoder) {
+ WebPIDelete(mDecoder);
+ WebPFreeDecBuffer(&mBuffer);
+ }
+}
+
+LexerResult nsWebPDecoder::ReadData() {
+ MOZ_ASSERT(mData);
+ MOZ_ASSERT(mLength > 0);
+
+ WebPDemuxer* demuxer = nullptr;
+ bool complete = mIteratorComplete;
+
+ if (mNeedDemuxer) {
+ WebPDemuxState state;
+ WebPData fragment;
+ fragment.bytes = mData;
+ fragment.size = mLength;
+
+ demuxer = WebPDemuxPartial(&fragment, &state);
+ if (state == WEBP_DEMUX_PARSE_ERROR) {
+ MOZ_LOG(
+ sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ReadData -- demux parse error\n", this));
+ WebPDemuxDelete(demuxer);
+ return LexerResult(TerminalState::FAILURE);
+ }
+
+ if (state == WEBP_DEMUX_PARSING_HEADER) {
+ WebPDemuxDelete(demuxer);
+ return LexerResult(Yield::NEED_MORE_DATA);
+ }
+
+ if (!demuxer) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ReadData -- no demuxer\n", this));
+ return LexerResult(TerminalState::FAILURE);
+ }
+
+ complete = complete || state == WEBP_DEMUX_DONE;
+ }
+
+ LexerResult rv(TerminalState::FAILURE);
+ if (!HasSize()) {
+ rv = ReadHeader(demuxer, complete);
+ } else {
+ rv = ReadPayload(demuxer, complete);
+ }
+
+ WebPDemuxDelete(demuxer);
+ return rv;
+}
+
+LexerResult nsWebPDecoder::DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) {
+ while (true) {
+ SourceBufferIterator::State state = SourceBufferIterator::COMPLETE;
+ if (!mIteratorComplete) {
+ state = aIterator.AdvanceOrScheduleResume(SIZE_MAX, aOnResume);
+
+ // We need to remember since we can't advance a complete iterator.
+ mIteratorComplete = state == SourceBufferIterator::COMPLETE;
+ }
+
+ if (state == SourceBufferIterator::WAITING) {
+ return LexerResult(Yield::NEED_MORE_DATA);
+ }
+
+ LexerResult rv = UpdateBuffer(aIterator, state);
+ if (rv.is<Yield>() && rv.as<Yield>() == Yield::NEED_MORE_DATA) {
+ // We need to check the iterator to see if more is available before
+ // giving up unless we are already complete.
+ if (mIteratorComplete) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::DoDecode -- read all data, "
+ "but needs more\n",
+ this));
+ return LexerResult(TerminalState::FAILURE);
+ }
+ continue;
+ }
+
+ return rv;
+ }
+}
+
+LexerResult nsWebPDecoder::UpdateBuffer(SourceBufferIterator& aIterator,
+ SourceBufferIterator::State aState) {
+ MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
+
+ switch (aState) {
+ case SourceBufferIterator::READY:
+ if (!aIterator.IsContiguous()) {
+ // We need to buffer. This should be rare, but expensive.
+ break;
+ }
+ if (!mData) {
+ // For as long as we hold onto an iterator, we know the data pointers
+ // to the chunks cannot change underneath us, so save the pointer to
+ // the first block.
+ MOZ_ASSERT(mLength == 0);
+ mData = reinterpret_cast<const uint8_t*>(aIterator.Data());
+ }
+ mLength += aIterator.Length();
+ return ReadData();
+ case SourceBufferIterator::COMPLETE:
+ if (!mData) {
+ // We must have hit an error, such as an OOM, when buffering the
+ // first set of encoded data.
+ MOZ_LOG(
+ sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::DoDecode -- complete no data\n", this));
+ return LexerResult(TerminalState::FAILURE);
+ }
+ return ReadData();
+ default:
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::DoDecode -- bad state\n", this));
+ return LexerResult(TerminalState::FAILURE);
+ }
+
+ // We need to buffer. If we have no data buffered, we need to get everything
+ // from the first chunk of the source buffer before appending the new data.
+ if (mBufferedData.empty()) {
+ MOZ_ASSERT(mData);
+ MOZ_ASSERT(mLength > 0);
+
+ if (!mBufferedData.append(mData, mLength)) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::DoDecode -- oom, initialize %zu\n",
+ this, mLength));
+ return LexerResult(TerminalState::FAILURE);
+ }
+
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::DoDecode -- buffered %zu bytes\n", this,
+ mLength));
+ }
+
+ // Append the incremental data from the iterator.
+ if (!mBufferedData.append(aIterator.Data(), aIterator.Length())) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::DoDecode -- oom, append %zu on %zu\n",
+ this, aIterator.Length(), mBufferedData.length()));
+ return LexerResult(TerminalState::FAILURE);
+ }
+
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::DoDecode -- buffered %zu -> %zu bytes\n",
+ this, aIterator.Length(), mBufferedData.length()));
+ mData = mBufferedData.begin();
+ mLength = mBufferedData.length();
+ return ReadData();
+}
+
+nsresult nsWebPDecoder::CreateFrame(const OrientedIntRect& aFrameRect) {
+ MOZ_ASSERT(HasSize());
+ MOZ_ASSERT(!mDecoder);
+
+ MOZ_LOG(
+ sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::CreateFrame -- frame %u, (%d, %d) %d x %d\n",
+ this, mCurrentFrame, aFrameRect.x, aFrameRect.y, aFrameRect.width,
+ aFrameRect.height));
+
+ if (aFrameRect.width <= 0 || aFrameRect.height <= 0) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::CreateFrame -- bad frame rect\n", this));
+ return NS_ERROR_FAILURE;
+ }
+
+ // If this is our first frame in an animation and it doesn't cover the
+ // full frame, then we are transparent even if there is no alpha
+ if (mCurrentFrame == 0 && !aFrameRect.IsEqualEdges(FullFrame())) {
+ MOZ_ASSERT(HasAnimation());
+ mFormat = SurfaceFormat::OS_RGBA;
+ PostHasTransparency();
+ }
+
+ WebPInitDecBuffer(&mBuffer);
+
+ switch (SurfaceFormat::OS_RGBA) {
+ case SurfaceFormat::B8G8R8A8:
+ mBuffer.colorspace = MODE_BGRA;
+ break;
+ case SurfaceFormat::A8R8G8B8:
+ mBuffer.colorspace = MODE_ARGB;
+ break;
+ case SurfaceFormat::R8G8B8A8:
+ mBuffer.colorspace = MODE_RGBA;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unknown OS_RGBA");
+ return NS_ERROR_FAILURE;
+ }
+
+ mDecoder = WebPINewDecoder(&mBuffer);
+ if (!mDecoder) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::CreateFrame -- create decoder error\n",
+ this));
+ return NS_ERROR_FAILURE;
+ }
+
+ // WebP doesn't guarantee that the alpha generated matches the hint in the
+ // header, so we always need to claim the input is BGRA. If the output is
+ // BGRX, swizzling will mask off the alpha channel.
+ SurfaceFormat inFormat = SurfaceFormat::OS_RGBA;
+
+ SurfacePipeFlags pipeFlags = SurfacePipeFlags();
+ if (mFormat == SurfaceFormat::OS_RGBA &&
+ !(GetSurfaceFlags() & SurfaceFlags::NO_PREMULTIPLY_ALPHA)) {
+ pipeFlags |= SurfacePipeFlags::PREMULTIPLY_ALPHA;
+ }
+
+ Maybe<AnimationParams> animParams;
+ if (!IsFirstFrameDecode()) {
+ animParams.emplace(aFrameRect.ToUnknownRect(), mTimeout, mCurrentFrame,
+ mBlend, mDisposal);
+ }
+
+ Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
+ this, Size(), OutputSize(), aFrameRect, inFormat, mFormat, animParams,
+ mTransform, pipeFlags);
+ if (!pipe) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::CreateFrame -- no pipe\n", this));
+ return NS_ERROR_FAILURE;
+ }
+
+ mFrameRect = aFrameRect;
+ mPipe = std::move(*pipe);
+ return NS_OK;
+}
+
+void nsWebPDecoder::EndFrame() {
+ MOZ_ASSERT(HasSize());
+ MOZ_ASSERT(mDecoder);
+
+ auto opacity = mFormat == SurfaceFormat::OS_RGBA ? Opacity::SOME_TRANSPARENCY
+ : Opacity::FULLY_OPAQUE;
+
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::EndFrame -- frame %u, opacity %d, "
+ "disposal %d, timeout %d, blend %d\n",
+ this, mCurrentFrame, (int)opacity, (int)mDisposal,
+ mTimeout.AsEncodedValueDeprecated(), (int)mBlend));
+
+ PostFrameStop(opacity);
+ WebPIDelete(mDecoder);
+ WebPFreeDecBuffer(&mBuffer);
+ mDecoder = nullptr;
+ mLastRow = 0;
+ ++mCurrentFrame;
+}
+
+void nsWebPDecoder::ApplyColorProfile(const char* aProfile, size_t aLength) {
+ MOZ_ASSERT(!mGotColorProfile);
+ mGotColorProfile = true;
+
+ if (mCMSMode == CMSMode::Off || !GetCMSOutputProfile() ||
+ (mCMSMode == CMSMode::TaggedOnly && !aProfile)) {
+ return;
+ }
+
+ if (!aProfile) {
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::ApplyColorProfile -- not tagged, use "
+ "sRGB transform\n",
+ this));
+ mTransform = GetCMSsRGBTransform(SurfaceFormat::OS_RGBA);
+ return;
+ }
+
+ mInProfile = qcms_profile_from_memory(aProfile, aLength);
+ if (!mInProfile) {
+ MOZ_LOG(
+ sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ApplyColorProfile -- bad color profile\n",
+ this));
+ return;
+ }
+
+ uint32_t profileSpace = qcms_profile_get_color_space(mInProfile);
+ if (profileSpace != icSigRgbData) {
+ // WebP doesn't produce grayscale data, this must be corrupt.
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ApplyColorProfile -- ignoring non-rgb "
+ "color profile\n",
+ this));
+ return;
+ }
+
+ // Calculate rendering intent.
+ int intent = gfxPlatform::GetRenderingIntent();
+ if (intent == -1) {
+ intent = qcms_profile_get_rendering_intent(mInProfile);
+ }
+
+ // Create the color management transform.
+ qcms_data_type type = gfxPlatform::GetCMSOSRGBAType();
+ mTransform = qcms_transform_create(mInProfile, type, GetCMSOutputProfile(),
+ type, (qcms_intent)intent);
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::ApplyColorProfile -- use tagged "
+ "transform\n",
+ this));
+}
+
+LexerResult nsWebPDecoder::ReadHeader(WebPDemuxer* aDemuxer, bool aIsComplete) {
+ MOZ_ASSERT(aDemuxer);
+
+ MOZ_LOG(
+ sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::ReadHeader -- %zu bytes\n", this, mLength));
+
+ uint32_t flags = WebPDemuxGetI(aDemuxer, WEBP_FF_FORMAT_FLAGS);
+
+ if (!IsMetadataDecode() && !mGotColorProfile) {
+ if (flags & WebPFeatureFlags::ICCP_FLAG) {
+ WebPChunkIterator iter;
+ if (WebPDemuxGetChunk(aDemuxer, "ICCP", 1, &iter)) {
+ ApplyColorProfile(reinterpret_cast<const char*>(iter.chunk.bytes),
+ iter.chunk.size);
+ WebPDemuxReleaseChunkIterator(&iter);
+
+ } else {
+ if (!aIsComplete) {
+ return LexerResult(Yield::NEED_MORE_DATA);
+ }
+
+ MOZ_LOG(sWebPLog, LogLevel::Warning,
+ ("[this=%p] nsWebPDecoder::ReadHeader header specified ICCP "
+ "but no ICCP chunk found, ignoring\n",
+ this));
+
+ ApplyColorProfile(nullptr, 0);
+ }
+ } else {
+ ApplyColorProfile(nullptr, 0);
+ }
+ }
+
+ if (flags & WebPFeatureFlags::ANIMATION_FLAG) {
+ // A metadata decode expects to get the correct first frame timeout which
+ // sadly is not provided by the normal WebP header parsing.
+ WebPIterator iter;
+ if (!WebPDemuxGetFrame(aDemuxer, 1, &iter)) {
+ return aIsComplete ? LexerResult(TerminalState::FAILURE)
+ : LexerResult(Yield::NEED_MORE_DATA);
+ }
+
+ PostIsAnimated(FrameTimeout::FromRawMilliseconds(iter.duration));
+ WebPDemuxReleaseIterator(&iter);
+ } else {
+ // Single frames don't need a demuxer to be created.
+ mNeedDemuxer = false;
+ }
+
+ uint32_t width = WebPDemuxGetI(aDemuxer, WEBP_FF_CANVAS_WIDTH);
+ uint32_t height = WebPDemuxGetI(aDemuxer, WEBP_FF_CANVAS_HEIGHT);
+ if (width > INT32_MAX || height > INT32_MAX) {
+ return LexerResult(TerminalState::FAILURE);
+ }
+
+ PostSize(width, height);
+
+ bool alpha = flags & WebPFeatureFlags::ALPHA_FLAG;
+ if (alpha) {
+ mFormat = SurfaceFormat::OS_RGBA;
+ PostHasTransparency();
+ }
+
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::ReadHeader -- %u x %u, alpha %d, "
+ "animation %d, metadata decode %d, first frame decode %d\n",
+ this, width, height, alpha, HasAnimation(), IsMetadataDecode(),
+ IsFirstFrameDecode()));
+
+ if (IsMetadataDecode()) {
+ return LexerResult(TerminalState::SUCCESS);
+ }
+
+ return ReadPayload(aDemuxer, aIsComplete);
+}
+
+LexerResult nsWebPDecoder::ReadPayload(WebPDemuxer* aDemuxer,
+ bool aIsComplete) {
+ if (!HasAnimation()) {
+ auto rv = ReadSingle(mData, mLength, FullFrame());
+ if (rv.is<TerminalState>() &&
+ rv.as<TerminalState>() == TerminalState::SUCCESS) {
+ PostDecodeDone();
+ }
+ return rv;
+ }
+ return ReadMultiple(aDemuxer, aIsComplete);
+}
+
+LexerResult nsWebPDecoder::ReadSingle(const uint8_t* aData, size_t aLength,
+ const OrientedIntRect& aFrameRect) {
+ MOZ_ASSERT(!IsMetadataDecode());
+ MOZ_ASSERT(aData);
+ MOZ_ASSERT(aLength > 0);
+
+ MOZ_LOG(
+ sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::ReadSingle -- %zu bytes\n", this, aLength));
+
+ if (!mDecoder && NS_FAILED(CreateFrame(aFrameRect))) {
+ return LexerResult(TerminalState::FAILURE);
+ }
+
+ bool complete;
+ do {
+ VP8StatusCode status = WebPIUpdate(mDecoder, aData, aLength);
+ switch (status) {
+ case VP8_STATUS_OK:
+ complete = true;
+ break;
+ case VP8_STATUS_SUSPENDED:
+ complete = false;
+ break;
+ default:
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ReadSingle -- append error %d\n",
+ this, status));
+ return LexerResult(TerminalState::FAILURE);
+ }
+
+ int lastRow = -1;
+ int width = 0;
+ int height = 0;
+ int stride = 0;
+ uint8_t* rowStart =
+ WebPIDecGetRGB(mDecoder, &lastRow, &width, &height, &stride);
+
+ MOZ_LOG(
+ sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::ReadSingle -- complete %d, read %d rows, "
+ "has %d rows available\n",
+ this, complete, mLastRow, lastRow));
+
+ if (!rowStart || lastRow == -1 || lastRow == mLastRow) {
+ return LexerResult(Yield::NEED_MORE_DATA);
+ }
+
+ if (width != mFrameRect.width || height != mFrameRect.height ||
+ stride < mFrameRect.width * 4 || lastRow > mFrameRect.height) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ReadSingle -- bad (w,h,s) = (%d, %d, "
+ "%d)\n",
+ this, width, height, stride));
+ return LexerResult(TerminalState::FAILURE);
+ }
+
+ for (int row = mLastRow; row < lastRow; row++) {
+ uint32_t* src = reinterpret_cast<uint32_t*>(rowStart + row * stride);
+ WriteState result = mPipe.WriteBuffer(src);
+
+ Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect();
+ if (invalidRect) {
+ PostInvalidation(invalidRect->mInputSpaceRect,
+ Some(invalidRect->mOutputSpaceRect));
+ }
+
+ if (result == WriteState::FAILURE) {
+ MOZ_LOG(sWebPLog, LogLevel::Error,
+ ("[this=%p] nsWebPDecoder::ReadSingle -- write pixels error\n",
+ this));
+ return LexerResult(TerminalState::FAILURE);
+ }
+
+ if (result == WriteState::FINISHED) {
+ MOZ_ASSERT(row == lastRow - 1, "There was more data to read?");
+ complete = true;
+ break;
+ }
+ }
+
+ mLastRow = lastRow;
+ } while (!complete);
+
+ if (!complete) {
+ return LexerResult(Yield::NEED_MORE_DATA);
+ }
+
+ EndFrame();
+ return LexerResult(TerminalState::SUCCESS);
+}
+
+LexerResult nsWebPDecoder::ReadMultiple(WebPDemuxer* aDemuxer,
+ bool aIsComplete) {
+ MOZ_ASSERT(!IsMetadataDecode());
+ MOZ_ASSERT(aDemuxer);
+
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::ReadMultiple\n", this));
+
+ bool complete = aIsComplete;
+ WebPIterator iter;
+ auto rv = LexerResult(Yield::NEED_MORE_DATA);
+ if (WebPDemuxGetFrame(aDemuxer, mCurrentFrame + 1, &iter)) {
+ switch (iter.blend_method) {
+ case WEBP_MUX_BLEND:
+ mBlend = BlendMethod::OVER;
+ break;
+ case WEBP_MUX_NO_BLEND:
+ mBlend = BlendMethod::SOURCE;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unhandled blend method");
+ break;
+ }
+
+ switch (iter.dispose_method) {
+ case WEBP_MUX_DISPOSE_NONE:
+ mDisposal = DisposalMethod::KEEP;
+ break;
+ case WEBP_MUX_DISPOSE_BACKGROUND:
+ mDisposal = DisposalMethod::CLEAR;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unhandled dispose method");
+ break;
+ }
+
+ mFormat = iter.has_alpha || mCurrentFrame > 0 ? SurfaceFormat::OS_RGBA
+ : SurfaceFormat::OS_RGBX;
+ mTimeout = FrameTimeout::FromRawMilliseconds(iter.duration);
+ OrientedIntRect frameRect(iter.x_offset, iter.y_offset, iter.width,
+ iter.height);
+
+ rv = ReadSingle(iter.fragment.bytes, iter.fragment.size, frameRect);
+ complete = complete && !WebPDemuxNextFrame(&iter);
+ WebPDemuxReleaseIterator(&iter);
+ }
+
+ if (rv.is<TerminalState>() &&
+ rv.as<TerminalState>() == TerminalState::SUCCESS) {
+ // If we extracted one frame, and it is not the last, we need to yield to
+ // the lexer to allow the upper layers to acknowledge the frame.
+ if (!complete && !IsFirstFrameDecode()) {
+ rv = LexerResult(Yield::OUTPUT_AVAILABLE);
+ } else {
+ uint32_t loopCount = WebPDemuxGetI(aDemuxer, WEBP_FF_LOOP_COUNT);
+
+ MOZ_LOG(sWebPLog, LogLevel::Debug,
+ ("[this=%p] nsWebPDecoder::ReadMultiple -- loop count %u\n", this,
+ loopCount));
+ PostDecodeDone(loopCount - 1);
+ }
+ }
+
+ return rv;
+}
+
+Maybe<Telemetry::HistogramID> nsWebPDecoder::SpeedHistogram() const {
+ return Some(Telemetry::IMAGE_DECODE_SPEED_WEBP);
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/decoders/nsWebPDecoder.h b/image/decoders/nsWebPDecoder.h
new file mode 100644
index 0000000000..e69122d19a
--- /dev/null
+++ b/image/decoders/nsWebPDecoder.h
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_decoders_nsWebPDecoder_h
+#define mozilla_image_decoders_nsWebPDecoder_h
+
+#include "Decoder.h"
+#include "webp/demux.h"
+#include "StreamingLexer.h"
+#include "SurfacePipe.h"
+
+namespace mozilla {
+namespace image {
+class RasterImage;
+
+class nsWebPDecoder final : public Decoder {
+ public:
+ virtual ~nsWebPDecoder();
+
+ DecoderType GetType() const override { return DecoderType::WEBP; }
+
+ protected:
+ LexerResult DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) override;
+ Maybe<Telemetry::HistogramID> SpeedHistogram() const override;
+
+ private:
+ friend class DecoderFactory;
+
+ // Decoders should only be instantiated via DecoderFactory.
+ explicit nsWebPDecoder(RasterImage* aImage);
+
+ void ApplyColorProfile(const char* aProfile, size_t aLength);
+
+ LexerResult UpdateBuffer(SourceBufferIterator& aIterator,
+ SourceBufferIterator::State aState);
+ LexerResult ReadData();
+ LexerResult ReadHeader(WebPDemuxer* aDemuxer, bool aIsComplete);
+ LexerResult ReadPayload(WebPDemuxer* aDemuxer, bool aIsComplete);
+
+ nsresult CreateFrame(const OrientedIntRect& aFrameRect);
+ void EndFrame();
+
+ LexerResult ReadSingle(const uint8_t* aData, size_t aLength,
+ const OrientedIntRect& aFrameRect);
+
+ LexerResult ReadMultiple(WebPDemuxer* aDemuxer, bool aIsComplete);
+
+ /// The SurfacePipe used to write to the output surface.
+ SurfacePipe mPipe;
+
+ /// The buffer used to accumulate data until the complete WebP header is
+ /// received, if and only if the iterator is discontiguous.
+ Vector<uint8_t> mBufferedData;
+
+ /// The libwebp output buffer descriptor pointing to the decoded data.
+ WebPDecBuffer mBuffer;
+
+ /// The libwebp incremental decoder descriptor, wraps mBuffer.
+ WebPIDecoder* mDecoder;
+
+ /// Blend method for the current frame.
+ BlendMethod mBlend;
+
+ /// Disposal method for the current frame.
+ DisposalMethod mDisposal;
+
+ /// Frame timeout for the current frame;
+ FrameTimeout mTimeout;
+
+ /// Surface format for the current frame.
+ gfx::SurfaceFormat mFormat;
+
+ /// Frame rect for the current frame.
+ OrientedIntRect mFrameRect;
+
+ /// The last row of decoded pixels written to mPipe.
+ int mLastRow;
+
+ /// Number of decoded frames.
+ uint32_t mCurrentFrame;
+
+ /// Pointer to the start of the contiguous encoded image data.
+ const uint8_t* mData;
+
+ /// Length of data pointed to by mData.
+ size_t mLength;
+
+ /// True if the iterator has reached its end.
+ bool mIteratorComplete;
+
+ /// True if this decoding pass requires a WebPDemuxer.
+ bool mNeedDemuxer;
+
+ /// True if we have setup the color profile for the image.
+ bool mGotColorProfile;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_decoders_nsWebPDecoder_h
diff --git a/image/encoders/bmp/moz.build b/image/encoders/bmp/moz.build
new file mode 100644
index 0000000000..783fd37005
--- /dev/null
+++ b/image/encoders/bmp/moz.build
@@ -0,0 +1,15 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+SOURCES += [
+ "nsBMPEncoder.cpp",
+]
+
+LOCAL_INCLUDES += [
+ "/image",
+]
+
+FINAL_LIBRARY = "xul"
diff --git a/image/encoders/bmp/nsBMPEncoder.cpp b/image/encoders/bmp/nsBMPEncoder.cpp
new file mode 100644
index 0000000000..697950d7af
--- /dev/null
+++ b/image/encoders/bmp/nsBMPEncoder.cpp
@@ -0,0 +1,716 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsCRT.h"
+#include "mozilla/EndianUtils.h"
+#include "mozilla/UniquePtrExtensions.h"
+#include "nsBMPEncoder.h"
+#include "nsString.h"
+#include "nsStreamUtils.h"
+#include "nsTArray.h"
+#include "mozilla/CheckedInt.h"
+#include "BMPHeaders.h"
+
+using namespace mozilla;
+using namespace mozilla::image;
+using namespace mozilla::image::bmp;
+
+NS_IMPL_ISUPPORTS(nsBMPEncoder, imgIEncoder, nsIInputStream,
+ nsIAsyncInputStream)
+
+nsBMPEncoder::nsBMPEncoder()
+ : mBMPInfoHeader{},
+ mImageBufferStart(nullptr),
+ mImageBufferCurr(0),
+ mImageBufferSize(0),
+ mImageBufferReadPoint(0),
+ mFinished(false),
+ mCallback(nullptr),
+ mCallbackTarget(nullptr),
+ mNotifyThreshold(0) {
+ this->mBMPFileHeader.filesize = 0;
+ this->mBMPFileHeader.reserved = 0;
+ this->mBMPFileHeader.dataoffset = 0;
+}
+
+nsBMPEncoder::~nsBMPEncoder() {
+ if (mImageBufferStart) {
+ free(mImageBufferStart);
+ mImageBufferStart = nullptr;
+ mImageBufferCurr = nullptr;
+ }
+}
+
+// nsBMPEncoder::InitFromData
+//
+// One output option is supported: bpp=<bpp_value>
+// bpp specifies the bits per pixel to use where bpp_value can be 24 or 32
+NS_IMETHODIMP
+nsBMPEncoder::InitFromData(const uint8_t* aData,
+ uint32_t aLength, // (unused, req'd by JS)
+ uint32_t aWidth, uint32_t aHeight, uint32_t aStride,
+ uint32_t aInputFormat,
+ const nsAString& aOutputOptions) {
+ // validate input format
+ if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA &&
+ aInputFormat != INPUT_FORMAT_HOSTARGB) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ CheckedInt32 check = CheckedInt32(aWidth) * 4;
+ if (MOZ_UNLIKELY(!check.isValid())) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // Stride is the padded width of each row, so it better be longer
+ if ((aInputFormat == INPUT_FORMAT_RGB && aStride < aWidth * 3) ||
+ ((aInputFormat == INPUT_FORMAT_RGBA ||
+ aInputFormat == INPUT_FORMAT_HOSTARGB) &&
+ aStride < aWidth * 4)) {
+ NS_WARNING("Invalid stride for InitFromData");
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ nsresult rv;
+ rv = StartImageEncode(aWidth, aHeight, aInputFormat, aOutputOptions);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ rv = AddImageFrame(aData, aLength, aWidth, aHeight, aStride, aInputFormat,
+ aOutputOptions);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ rv = EndImageEncode();
+ return rv;
+}
+
+// Just a helper method to make it explicit in calculations that we are dealing
+// with bytes and not bits
+static inline uint16_t BytesPerPixel(uint16_t aBPP) { return aBPP / 8; }
+
+// Calculates the number of padding bytes that are needed per row of image data
+static inline uint32_t PaddingBytes(uint16_t aBPP, uint32_t aWidth) {
+ uint32_t rowSize = aWidth * BytesPerPixel(aBPP);
+ uint8_t paddingSize = 0;
+ if (rowSize % 4) {
+ paddingSize = (4 - (rowSize % 4));
+ }
+ return paddingSize;
+}
+
+// See ::InitFromData for other info.
+NS_IMETHODIMP
+nsBMPEncoder::StartImageEncode(uint32_t aWidth, uint32_t aHeight,
+ uint32_t aInputFormat,
+ const nsAString& aOutputOptions) {
+ // can't initialize more than once
+ if (mImageBufferStart || mImageBufferCurr) {
+ return NS_ERROR_ALREADY_INITIALIZED;
+ }
+
+ // validate input format
+ if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA &&
+ aInputFormat != INPUT_FORMAT_HOSTARGB) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // parse and check any provided output options
+ Version version;
+ uint16_t bpp;
+ nsresult rv = ParseOptions(aOutputOptions, version, bpp);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ MOZ_ASSERT(bpp <= 32);
+
+ rv = InitFileHeader(version, bpp, aWidth, aHeight);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = InitInfoHeader(version, bpp, aWidth, aHeight);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ mImageBufferSize = mBMPFileHeader.filesize;
+ mImageBufferStart = static_cast<uint8_t*>(malloc(mImageBufferSize));
+ if (!mImageBufferStart) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ mImageBufferCurr = mImageBufferStart;
+
+ EncodeFileHeader();
+ EncodeInfoHeader();
+
+ return NS_OK;
+}
+
+// Returns the number of bytes in the image buffer used.
+// For a BMP file, this is all bytes in the buffer.
+NS_IMETHODIMP
+nsBMPEncoder::GetImageBufferUsed(uint32_t* aOutputSize) {
+ NS_ENSURE_ARG_POINTER(aOutputSize);
+ *aOutputSize = mImageBufferSize;
+ return NS_OK;
+}
+
+// Returns a pointer to the start of the image buffer
+NS_IMETHODIMP
+nsBMPEncoder::GetImageBuffer(char** aOutputBuffer) {
+ NS_ENSURE_ARG_POINTER(aOutputBuffer);
+ *aOutputBuffer = reinterpret_cast<char*>(mImageBufferStart);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsBMPEncoder::AddImageFrame(const uint8_t* aData,
+ uint32_t aLength, // (unused, req'd by JS)
+ uint32_t aWidth, uint32_t aHeight, uint32_t aStride,
+ uint32_t aInputFormat,
+ const nsAString& aFrameOptions) {
+ // must be initialized
+ if (!mImageBufferStart || !mImageBufferCurr) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ // validate input format
+ if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA &&
+ aInputFormat != INPUT_FORMAT_HOSTARGB) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (mBMPInfoHeader.width < 0) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ CheckedUint32 size = CheckedUint32(mBMPInfoHeader.width) *
+ CheckedUint32(BytesPerPixel(mBMPInfoHeader.bpp));
+ if (MOZ_UNLIKELY(!size.isValid())) {
+ return NS_ERROR_FAILURE;
+ }
+
+ auto row = MakeUniqueFallible<uint8_t[]>(size.value());
+ if (!row) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ CheckedUint32 check = CheckedUint32(mBMPInfoHeader.height) * aStride;
+ if (MOZ_UNLIKELY(!check.isValid())) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // write each row: if we add more input formats, we may want to
+ // generalize the conversions
+ if (aInputFormat == INPUT_FORMAT_HOSTARGB) {
+ // BMP requires RGBA with post-multiplied alpha, so we need to convert
+ for (int32_t y = mBMPInfoHeader.height - 1; y >= 0; y--) {
+ ConvertHostARGBRow(&aData[y * aStride], row, mBMPInfoHeader.width);
+ if (mBMPInfoHeader.bpp == 24) {
+ EncodeImageDataRow24(row.get());
+ } else {
+ EncodeImageDataRow32(row.get());
+ }
+ }
+ } else if (aInputFormat == INPUT_FORMAT_RGBA) {
+ // simple RGBA, no conversion needed
+ for (int32_t y = 0; y < mBMPInfoHeader.height; y++) {
+ if (mBMPInfoHeader.bpp == 24) {
+ EncodeImageDataRow24(row.get());
+ } else {
+ EncodeImageDataRow32(row.get());
+ }
+ }
+ } else if (aInputFormat == INPUT_FORMAT_RGB) {
+ // simple RGB, no conversion needed
+ for (int32_t y = 0; y < mBMPInfoHeader.height; y++) {
+ if (mBMPInfoHeader.bpp == 24) {
+ EncodeImageDataRow24(&aData[y * aStride]);
+ } else {
+ EncodeImageDataRow32(&aData[y * aStride]);
+ }
+ }
+ } else {
+ MOZ_ASSERT_UNREACHABLE("Bad format type");
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsBMPEncoder::EndImageEncode() {
+ // must be initialized
+ if (!mImageBufferStart || !mImageBufferCurr) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ mFinished = true;
+ NotifyListener();
+
+ // if output callback can't get enough memory, it will free our buffer
+ if (!mImageBufferStart || !mImageBufferCurr) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ return NS_OK;
+}
+
+// Parses the encoder options and sets the bits per pixel to use
+// See InitFromData for a description of the parse options
+nsresult nsBMPEncoder::ParseOptions(const nsAString& aOptions,
+ Version& aVersionOut, uint16_t& aBppOut) {
+ aVersionOut = VERSION_3;
+ aBppOut = 24;
+
+ // Parse the input string into a set of name/value pairs.
+ // From a format like: name=value;bpp=<bpp_value>;name=value
+ // to format: [0] = name=value, [1] = bpp=<bpp_value>, [2] = name=value
+ nsTArray<nsCString> nameValuePairs;
+ ParseString(NS_ConvertUTF16toUTF8(aOptions), ';', nameValuePairs);
+
+ // For each name/value pair in the set
+ for (uint32_t i = 0; i < nameValuePairs.Length(); ++i) {
+ // Split the name value pair [0] = name, [1] = value
+ nsTArray<nsCString> nameValuePair;
+ ParseString(nameValuePairs[i], '=', nameValuePair);
+ if (nameValuePair.Length() != 2) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // Parse the bpp portion of the string name=value;version=<version_value>;
+ // name=value
+ if (nameValuePair[0].Equals("version",
+ nsCaseInsensitiveCStringComparator)) {
+ if (nameValuePair[1].EqualsLiteral("3")) {
+ aVersionOut = VERSION_3;
+ } else if (nameValuePair[1].EqualsLiteral("5")) {
+ aVersionOut = VERSION_5;
+ } else {
+ return NS_ERROR_INVALID_ARG;
+ }
+ }
+
+ // Parse the bpp portion of the string name=value;bpp=<bpp_value>;name=value
+ if (nameValuePair[0].Equals("bpp", nsCaseInsensitiveCStringComparator)) {
+ if (nameValuePair[1].EqualsLiteral("24")) {
+ aBppOut = 24;
+ } else if (nameValuePair[1].EqualsLiteral("32")) {
+ aBppOut = 32;
+ } else {
+ return NS_ERROR_INVALID_ARG;
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsBMPEncoder::Close() {
+ if (mImageBufferStart) {
+ free(mImageBufferStart);
+ mImageBufferStart = nullptr;
+ mImageBufferSize = 0;
+ mImageBufferReadPoint = 0;
+ mImageBufferCurr = nullptr;
+ }
+
+ return NS_OK;
+}
+
+// Obtains the available bytes to read
+NS_IMETHODIMP
+nsBMPEncoder::Available(uint64_t* _retval) {
+ if (!mImageBufferStart || !mImageBufferCurr) {
+ return NS_BASE_STREAM_CLOSED;
+ }
+
+ *_retval = GetCurrentImageBufferOffset() - mImageBufferReadPoint;
+ return NS_OK;
+}
+
+// Obtains the stream's status
+NS_IMETHODIMP
+nsBMPEncoder::StreamStatus() {
+ return mImageBufferStart && mImageBufferCurr ? NS_OK : NS_BASE_STREAM_CLOSED;
+}
+
+// [noscript] Reads bytes which are available
+NS_IMETHODIMP
+nsBMPEncoder::Read(char* aBuf, uint32_t aCount, uint32_t* _retval) {
+ return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, _retval);
+}
+
+// [noscript] Reads segments
+NS_IMETHODIMP
+nsBMPEncoder::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
+ uint32_t aCount, uint32_t* _retval) {
+ uint32_t maxCount = GetCurrentImageBufferOffset() - mImageBufferReadPoint;
+ if (maxCount == 0) {
+ *_retval = 0;
+ return mFinished ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK;
+ }
+
+ if (aCount > maxCount) {
+ aCount = maxCount;
+ }
+ nsresult rv = aWriter(
+ this, aClosure,
+ reinterpret_cast<const char*>(mImageBufferStart + mImageBufferReadPoint),
+ 0, aCount, _retval);
+ if (NS_SUCCEEDED(rv)) {
+ NS_ASSERTION(*_retval <= aCount, "bad write count");
+ mImageBufferReadPoint += *_retval;
+ }
+ // errors returned from the writer end here!
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsBMPEncoder::IsNonBlocking(bool* _retval) {
+ *_retval = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsBMPEncoder::AsyncWait(nsIInputStreamCallback* aCallback, uint32_t aFlags,
+ uint32_t aRequestedCount, nsIEventTarget* aTarget) {
+ if (aFlags != 0) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+
+ if (mCallback || mCallbackTarget) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ mCallbackTarget = aTarget;
+ // 0 means "any number of bytes except 0"
+ mNotifyThreshold = aRequestedCount;
+ if (!aRequestedCount) {
+ mNotifyThreshold = 1024; // We don't want to notify incessantly
+ }
+
+ // We set the callback absolutely last, because NotifyListener uses it to
+ // determine if someone needs to be notified. If we don't set it last,
+ // NotifyListener might try to fire off a notification to a null target
+ // which will generally cause non-threadsafe objects to be used off the
+ // main thread
+ mCallback = aCallback;
+
+ // What we are being asked for may be present already
+ NotifyListener();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsBMPEncoder::CloseWithStatus(nsresult aStatus) { return Close(); }
+
+// nsBMPEncoder::ConvertHostARGBRow
+//
+// Our colors are stored with premultiplied alphas, but we need
+// an output with no alpha in machine-independent byte order.
+//
+void nsBMPEncoder::ConvertHostARGBRow(const uint8_t* aSrc,
+ const UniquePtr<uint8_t[]>& aDest,
+ uint32_t aPixelWidth) {
+ uint16_t bytes = BytesPerPixel(mBMPInfoHeader.bpp);
+
+ if (mBMPInfoHeader.bpp == 32) {
+ for (uint32_t x = 0; x < aPixelWidth; x++) {
+ const uint32_t& pixelIn = ((const uint32_t*)(aSrc))[x];
+ uint8_t* pixelOut = &aDest[x * bytes];
+
+ pixelOut[0] = (pixelIn & 0x00ff0000) >> 16;
+ pixelOut[1] = (pixelIn & 0x0000ff00) >> 8;
+ pixelOut[2] = (pixelIn & 0x000000ff) >> 0;
+ pixelOut[3] = (pixelIn & 0xff000000) >> 24;
+ }
+ } else {
+ for (uint32_t x = 0; x < aPixelWidth; x++) {
+ const uint32_t& pixelIn = ((const uint32_t*)(aSrc))[x];
+ uint8_t* pixelOut = &aDest[x * bytes];
+
+ pixelOut[0] = (pixelIn & 0xff0000) >> 16;
+ pixelOut[1] = (pixelIn & 0x00ff00) >> 8;
+ pixelOut[2] = (pixelIn & 0x0000ff) >> 0;
+ }
+ }
+}
+
+void nsBMPEncoder::NotifyListener() {
+ if (mCallback && (GetCurrentImageBufferOffset() - mImageBufferReadPoint >=
+ mNotifyThreshold ||
+ mFinished)) {
+ nsCOMPtr<nsIInputStreamCallback> callback;
+ if (mCallbackTarget) {
+ callback = NS_NewInputStreamReadyEvent("nsBMPEncoder::NotifyListener",
+ mCallback, mCallbackTarget);
+ } else {
+ callback = mCallback;
+ }
+
+ NS_ASSERTION(callback, "Shouldn't fail to make the callback");
+ // Null the callback first because OnInputStreamReady could
+ // reenter AsyncWait
+ mCallback = nullptr;
+ mCallbackTarget = nullptr;
+ mNotifyThreshold = 0;
+
+ callback->OnInputStreamReady(this);
+ }
+}
+
+// Initializes the BMP file header mBMPFileHeader to the passed in values
+nsresult nsBMPEncoder::InitFileHeader(Version aVersion, uint16_t aBPP,
+ uint32_t aWidth, uint32_t aHeight) {
+ memset(&mBMPFileHeader, 0, sizeof(mBMPFileHeader));
+ mBMPFileHeader.signature[0] = 'B';
+ mBMPFileHeader.signature[1] = 'M';
+
+ if (aVersion == VERSION_3) {
+ mBMPFileHeader.dataoffset = FILE_HEADER_LENGTH + InfoHeaderLength::WIN_V3;
+ } else { // aVersion == 5
+ mBMPFileHeader.dataoffset = FILE_HEADER_LENGTH + InfoHeaderLength::WIN_V5;
+ }
+
+ // The color table is present only if BPP is <= 8
+ if (aBPP <= 8) {
+ uint32_t numColors = 1 << aBPP;
+ mBMPFileHeader.dataoffset += 4 * numColors;
+ CheckedUint32 filesize = CheckedUint32(mBMPFileHeader.dataoffset) +
+ CheckedUint32(aWidth) * aHeight;
+ if (MOZ_UNLIKELY(!filesize.isValid())) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ mBMPFileHeader.filesize = filesize.value();
+ } else {
+ CheckedUint32 filesize = CheckedUint32(mBMPFileHeader.dataoffset) +
+ (CheckedUint32(aWidth) * BytesPerPixel(aBPP) +
+ PaddingBytes(aBPP, aWidth)) *
+ aHeight;
+ if (MOZ_UNLIKELY(!filesize.isValid())) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ mBMPFileHeader.filesize = filesize.value();
+ }
+
+ mBMPFileHeader.reserved = 0;
+
+ return NS_OK;
+}
+
+#define ENCODE(pImageBufferCurr, value) \
+ memcpy(*pImageBufferCurr, &value, sizeof value); \
+ *pImageBufferCurr += sizeof value;
+
+// Initializes the bitmap info header mBMPInfoHeader to the passed in values
+nsresult nsBMPEncoder::InitInfoHeader(Version aVersion, uint16_t aBPP,
+ uint32_t aWidth, uint32_t aHeight) {
+ memset(&mBMPInfoHeader, 0, sizeof(mBMPInfoHeader));
+ if (aVersion == VERSION_3) {
+ mBMPInfoHeader.bihsize = InfoHeaderLength::WIN_V3;
+ } else {
+ MOZ_ASSERT(aVersion == VERSION_5);
+ mBMPInfoHeader.bihsize = InfoHeaderLength::WIN_V5;
+ }
+
+ CheckedInt32 width(aWidth);
+ CheckedInt32 height(aHeight);
+ if (MOZ_UNLIKELY(!width.isValid() || !height.isValid())) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ mBMPInfoHeader.width = width.value();
+ mBMPInfoHeader.height = height.value();
+
+ mBMPInfoHeader.planes = 1;
+ mBMPInfoHeader.bpp = aBPP;
+ mBMPInfoHeader.compression = 0;
+ mBMPInfoHeader.colors = 0;
+ mBMPInfoHeader.important_colors = 0;
+
+ CheckedUint32 check = CheckedUint32(aWidth) * BytesPerPixel(aBPP);
+ if (MOZ_UNLIKELY(!check.isValid())) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (aBPP <= 8) {
+ CheckedUint32 imagesize = CheckedUint32(aWidth) * aHeight;
+ if (MOZ_UNLIKELY(!imagesize.isValid())) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ mBMPInfoHeader.image_size = imagesize.value();
+ } else {
+ CheckedUint32 imagesize = (CheckedUint32(aWidth) * BytesPerPixel(aBPP) +
+ PaddingBytes(aBPP, aWidth)) *
+ CheckedUint32(aHeight);
+ if (MOZ_UNLIKELY(!imagesize.isValid())) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ mBMPInfoHeader.image_size = imagesize.value();
+ }
+ mBMPInfoHeader.xppm = 0;
+ mBMPInfoHeader.yppm = 0;
+ if (aVersion >= VERSION_5) {
+ mBMPInfoHeader.red_mask = 0x000000FF;
+ mBMPInfoHeader.green_mask = 0x0000FF00;
+ mBMPInfoHeader.blue_mask = 0x00FF0000;
+ mBMPInfoHeader.alpha_mask = 0xFF000000;
+ mBMPInfoHeader.color_space = V5InfoHeader::COLOR_SPACE_LCS_SRGB;
+ mBMPInfoHeader.white_point.r.x = 0;
+ mBMPInfoHeader.white_point.r.y = 0;
+ mBMPInfoHeader.white_point.r.z = 0;
+ mBMPInfoHeader.white_point.g.x = 0;
+ mBMPInfoHeader.white_point.g.y = 0;
+ mBMPInfoHeader.white_point.g.z = 0;
+ mBMPInfoHeader.white_point.b.x = 0;
+ mBMPInfoHeader.white_point.b.y = 0;
+ mBMPInfoHeader.white_point.b.z = 0;
+ mBMPInfoHeader.gamma_red = 0;
+ mBMPInfoHeader.gamma_green = 0;
+ mBMPInfoHeader.gamma_blue = 0;
+ mBMPInfoHeader.intent = 0;
+ mBMPInfoHeader.profile_offset = 0;
+ mBMPInfoHeader.profile_size = 0;
+ mBMPInfoHeader.reserved = 0;
+ }
+
+ return NS_OK;
+}
+
+// Encodes the BMP file header mBMPFileHeader
+void nsBMPEncoder::EncodeFileHeader() {
+ FileHeader littleEndianBFH = mBMPFileHeader;
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianBFH.filesize, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianBFH.reserved, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianBFH.dataoffset, 1);
+
+ ENCODE(&mImageBufferCurr, littleEndianBFH.signature);
+ ENCODE(&mImageBufferCurr, littleEndianBFH.filesize);
+ ENCODE(&mImageBufferCurr, littleEndianBFH.reserved);
+ ENCODE(&mImageBufferCurr, littleEndianBFH.dataoffset);
+}
+
+// Encodes the BMP info header mBMPInfoHeader
+void nsBMPEncoder::EncodeInfoHeader() {
+ V5InfoHeader littleEndianmBIH = mBMPInfoHeader;
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.bihsize, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.width, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.height, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.planes, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.bpp, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.compression, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.image_size, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.xppm, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.yppm, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.colors, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.important_colors,
+ 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.red_mask, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.green_mask, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.blue_mask, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.alpha_mask, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.color_space, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.r.x, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.r.y, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.r.z, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.g.x, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.g.y, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.g.z, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.b.x, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.b.y, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.b.z, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.gamma_red, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.gamma_green, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.gamma_blue, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.intent, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.profile_offset, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.profile_size, 1);
+
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.bihsize);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.width);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.height);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.planes);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.bpp);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.compression);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.image_size);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.xppm);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.yppm);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.colors);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.important_colors);
+
+ if (mBMPInfoHeader.bihsize > InfoHeaderLength::WIN_V3) {
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.red_mask);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.green_mask);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.blue_mask);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.alpha_mask);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.color_space);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.white_point.r.x);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.white_point.r.y);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.white_point.r.z);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.white_point.g.x);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.white_point.g.y);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.white_point.g.z);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.white_point.b.x);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.white_point.b.y);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.white_point.b.z);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.gamma_red);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.gamma_green);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.gamma_blue);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.intent);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.profile_offset);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.profile_size);
+ ENCODE(&mImageBufferCurr, littleEndianmBIH.reserved);
+ }
+}
+
+// Sets a pixel in the image buffer that doesn't have alpha data
+static inline void SetPixel24(uint8_t*& imageBufferCurr, uint8_t aRed,
+ uint8_t aGreen, uint8_t aBlue) {
+ *imageBufferCurr = aBlue;
+ *(imageBufferCurr + 1) = aGreen;
+ *(imageBufferCurr + 2) = aRed;
+}
+
+// Sets a pixel in the image buffer with alpha data
+static inline void SetPixel32(uint8_t*& imageBufferCurr, uint8_t aRed,
+ uint8_t aGreen, uint8_t aBlue,
+ uint8_t aAlpha = 0xFF) {
+ *imageBufferCurr = aBlue;
+ *(imageBufferCurr + 1) = aGreen;
+ *(imageBufferCurr + 2) = aRed;
+ *(imageBufferCurr + 3) = aAlpha;
+}
+
+// Encodes a row of image data which does not have alpha data
+void nsBMPEncoder::EncodeImageDataRow24(const uint8_t* aData) {
+ for (int32_t x = 0; x < mBMPInfoHeader.width; x++) {
+ uint32_t pos = x * BytesPerPixel(mBMPInfoHeader.bpp);
+ SetPixel24(mImageBufferCurr, aData[pos], aData[pos + 1], aData[pos + 2]);
+ mImageBufferCurr += BytesPerPixel(mBMPInfoHeader.bpp);
+ }
+
+ for (uint32_t x = 0;
+ x < PaddingBytes(mBMPInfoHeader.bpp, mBMPInfoHeader.width); x++) {
+ *mImageBufferCurr++ = 0;
+ }
+}
+
+// Encodes a row of image data which does have alpha data
+void nsBMPEncoder::EncodeImageDataRow32(const uint8_t* aData) {
+ for (int32_t x = 0; x < mBMPInfoHeader.width; x++) {
+ uint32_t pos = x * BytesPerPixel(mBMPInfoHeader.bpp);
+ SetPixel32(mImageBufferCurr, aData[pos], aData[pos + 1], aData[pos + 2],
+ aData[pos + 3]);
+ mImageBufferCurr += 4;
+ }
+
+ for (uint32_t x = 0;
+ x < PaddingBytes(mBMPInfoHeader.bpp, mBMPInfoHeader.width); x++) {
+ *mImageBufferCurr++ = 0;
+ }
+}
diff --git a/image/encoders/bmp/nsBMPEncoder.h b/image/encoders/bmp/nsBMPEncoder.h
new file mode 100644
index 0000000000..1f40d9df34
--- /dev/null
+++ b/image/encoders/bmp/nsBMPEncoder.h
@@ -0,0 +1,150 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_encoders_bmp_nsBMPEncoder_h
+#define mozilla_image_encoders_bmp_nsBMPEncoder_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/ReentrantMonitor.h"
+#include "mozilla/UniquePtr.h"
+
+#include "imgIEncoder.h"
+
+#include "nsCOMPtr.h"
+
+#define NS_BMPENCODER_CID \
+ { /* 13a5320c-4c91-4FA4-bd16-b081a3ba8c0b */ \
+ 0x13a5320c, 0x4c91, 0x4fa4, { \
+ 0xbd, 0x16, 0xb0, 0x81, 0xa3, 0Xba, 0x8c, 0x0b \
+ } \
+ }
+
+namespace mozilla {
+namespace image {
+namespace bmp {
+
+struct FileHeader {
+ char signature[2]; // String "BM".
+ uint32_t filesize; // File size.
+ int32_t reserved; // Zero.
+ uint32_t dataoffset; // Offset to raster data.
+};
+
+struct XYZ {
+ int32_t x, y, z;
+};
+
+struct XYZTriple {
+ XYZ r, g, b;
+};
+
+struct V5InfoHeader {
+ uint32_t bihsize; // Header size
+ int32_t width; // Uint16 in OS/2 BMPs
+ int32_t height; // Uint16 in OS/2 BMPs
+ uint16_t planes; // =1
+ uint16_t bpp; // Bits per pixel.
+ uint32_t compression; // See Compression for valid values
+ uint32_t image_size; // (compressed) image size. Can be 0 if
+ // compression==0
+ uint32_t xppm; // Pixels per meter, horizontal
+ uint32_t yppm; // Pixels per meter, vertical
+ uint32_t colors; // Used Colors
+ uint32_t important_colors; // Number of important colors. 0=all
+ // The rest of the header is not available in WIN_V3 BMP Files
+ uint32_t red_mask; // Bits used for red component
+ uint32_t green_mask; // Bits used for green component
+ uint32_t blue_mask; // Bits used for blue component
+ uint32_t alpha_mask; // Bits used for alpha component
+ uint32_t color_space; // 0x73524742=LCS_sRGB ...
+ // These members are unused unless color_space == LCS_CALIBRATED_RGB
+ XYZTriple white_point; // Logical white point
+ uint32_t gamma_red; // Red gamma component
+ uint32_t gamma_green; // Green gamma component
+ uint32_t gamma_blue; // Blue gamma component
+ uint32_t intent; // Rendering intent
+ // These members are unused unless color_space == LCS_PROFILE_*
+ uint32_t profile_offset; // Offset to profile data in bytes
+ uint32_t profile_size; // Size of profile data in bytes
+ uint32_t reserved; // =0
+
+ static const uint32_t COLOR_SPACE_LCS_SRGB = 0x73524742;
+};
+
+} // namespace bmp
+} // namespace image
+} // namespace mozilla
+
+// Provides BMP encoding functionality. Use InitFromData() to do the
+// encoding. See that function definition for encoding options.
+
+class nsBMPEncoder final : public imgIEncoder {
+ typedef mozilla::ReentrantMonitor ReentrantMonitor;
+
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_IMGIENCODER
+ NS_DECL_NSIINPUTSTREAM
+ NS_DECL_NSIASYNCINPUTSTREAM
+
+ nsBMPEncoder();
+
+ protected:
+ ~nsBMPEncoder();
+
+ enum Version { VERSION_3 = 3, VERSION_5 = 5 };
+
+ // See InitData in the cpp for valid parse options
+ nsresult ParseOptions(const nsAString& aOptions, Version& aVersionOut,
+ uint16_t& aBppOut);
+ // Obtains data with no alpha in machine-independent byte order
+ void ConvertHostARGBRow(const uint8_t* aSrc,
+ const mozilla::UniquePtr<uint8_t[]>& aDest,
+ uint32_t aPixelWidth);
+ // Thread safe notify listener
+ void NotifyListener();
+
+ // Initializes the bitmap file header member mBMPFileHeader
+ nsresult InitFileHeader(Version aVersion, uint16_t aBPP, uint32_t aWidth,
+ uint32_t aHeight);
+ // Initializes the bitmap info header member mBMPInfoHeader
+ nsresult InitInfoHeader(Version aVersion, uint16_t aBPP, uint32_t aWidth,
+ uint32_t aHeight);
+
+ // Encodes the bitmap file header member mBMPFileHeader
+ void EncodeFileHeader();
+ // Encodes the bitmap info header member mBMPInfoHeader
+ void EncodeInfoHeader();
+ // Encodes a row of image data which does not have alpha data
+ void EncodeImageDataRow24(const uint8_t* aData);
+ // Encodes a row of image data which does have alpha data
+ void EncodeImageDataRow32(const uint8_t* aData);
+ // Obtains the current offset filled up to for the image buffer
+ inline int32_t GetCurrentImageBufferOffset() {
+ return static_cast<int32_t>(mImageBufferCurr - mImageBufferStart);
+ }
+
+ // These headers will always contain endian independent stuff
+ // They store the BMP headers which will be encoded
+ mozilla::image::bmp::FileHeader mBMPFileHeader;
+ mozilla::image::bmp::V5InfoHeader mBMPInfoHeader;
+
+ // Keeps track of the start of the image buffer
+ uint8_t* mImageBufferStart;
+ // Keeps track of the current position in the image buffer
+ uint8_t* mImageBufferCurr;
+ // Keeps track of the image buffer size
+ uint32_t mImageBufferSize;
+ // Keeps track of the number of bytes in the image buffer which are read
+ uint32_t mImageBufferReadPoint;
+ // Stores true if the image is done being encoded
+ bool mFinished;
+
+ nsCOMPtr<nsIInputStreamCallback> mCallback;
+ nsCOMPtr<nsIEventTarget> mCallbackTarget;
+ uint32_t mNotifyThreshold;
+};
+
+#endif // mozilla_image_encoders_bmp_nsBMPEncoder_h
diff --git a/image/encoders/ico/moz.build b/image/encoders/ico/moz.build
new file mode 100644
index 0000000000..27e41489fd
--- /dev/null
+++ b/image/encoders/ico/moz.build
@@ -0,0 +1,20 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+SOURCES += [
+ "nsICOEncoder.cpp",
+]
+
+# Decoders need RasterImage.h
+LOCAL_INCLUDES += [
+ "/image",
+ "/image/encoders/bmp",
+ "/image/encoders/png",
+]
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+FINAL_LIBRARY = "xul"
diff --git a/image/encoders/ico/nsICOEncoder.cpp b/image/encoders/ico/nsICOEncoder.cpp
new file mode 100644
index 0000000000..518acc9a0b
--- /dev/null
+++ b/image/encoders/ico/nsICOEncoder.cpp
@@ -0,0 +1,499 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsCRT.h"
+#include "mozilla/EndianUtils.h"
+#include "nsBMPEncoder.h"
+#include "BMPHeaders.h"
+#include "nsPNGEncoder.h"
+#include "nsICOEncoder.h"
+#include "nsString.h"
+#include "nsStreamUtils.h"
+#include "nsTArray.h"
+
+using namespace mozilla;
+using namespace mozilla::image;
+
+NS_IMPL_ISUPPORTS(nsICOEncoder, imgIEncoder, nsIInputStream,
+ nsIAsyncInputStream)
+
+nsICOEncoder::nsICOEncoder()
+ : mICOFileHeader{},
+ mICODirEntry{},
+ mImageBufferStart(nullptr),
+ mImageBufferCurr(0),
+ mImageBufferSize(0),
+ mImageBufferReadPoint(0),
+ mFinished(false),
+ mUsePNG(true),
+ mNotifyThreshold(0) {}
+
+nsICOEncoder::~nsICOEncoder() {
+ if (mImageBufferStart) {
+ free(mImageBufferStart);
+ mImageBufferStart = nullptr;
+ mImageBufferCurr = nullptr;
+ }
+}
+
+// nsICOEncoder::InitFromData
+// Two output options are supported: format=<png|bmp>;bpp=<bpp_value>
+// format specifies whether to use png or bitmap format
+// bpp specifies the bits per pixel to use where bpp_value can be 24 or 32
+NS_IMETHODIMP
+nsICOEncoder::InitFromData(const uint8_t* aData, uint32_t aLength,
+ uint32_t aWidth, uint32_t aHeight, uint32_t aStride,
+ uint32_t aInputFormat,
+ const nsAString& aOutputOptions) {
+ // validate input format
+ if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA &&
+ aInputFormat != INPUT_FORMAT_HOSTARGB) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // Stride is the padded width of each row, so it better be longer
+ if ((aInputFormat == INPUT_FORMAT_RGB && aStride < aWidth * 3) ||
+ ((aInputFormat == INPUT_FORMAT_RGBA ||
+ aInputFormat == INPUT_FORMAT_HOSTARGB) &&
+ aStride < aWidth * 4)) {
+ NS_WARNING("Invalid stride for InitFromData");
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ nsresult rv;
+ rv = StartImageEncode(aWidth, aHeight, aInputFormat, aOutputOptions);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = AddImageFrame(aData, aLength, aWidth, aHeight, aStride, aInputFormat,
+ aOutputOptions);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = EndImageEncode();
+ return rv;
+}
+
+// Returns the number of bytes in the image buffer used
+// For an ICO file, this is all bytes in the buffer.
+NS_IMETHODIMP
+nsICOEncoder::GetImageBufferUsed(uint32_t* aOutputSize) {
+ NS_ENSURE_ARG_POINTER(aOutputSize);
+ *aOutputSize = mImageBufferSize;
+ return NS_OK;
+}
+
+// Returns a pointer to the start of the image buffer
+NS_IMETHODIMP
+nsICOEncoder::GetImageBuffer(char** aOutputBuffer) {
+ NS_ENSURE_ARG_POINTER(aOutputBuffer);
+ *aOutputBuffer = reinterpret_cast<char*>(mImageBufferStart);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsICOEncoder::AddImageFrame(const uint8_t* aData, uint32_t aLength,
+ uint32_t aWidth, uint32_t aHeight, uint32_t aStride,
+ uint32_t aInputFormat,
+ const nsAString& aFrameOptions) {
+ if (mUsePNG) {
+ mContainedEncoder = new nsPNGEncoder();
+ nsresult rv;
+ nsAutoString noParams;
+ rv = mContainedEncoder->InitFromData(aData, aLength, aWidth, aHeight,
+ aStride, aInputFormat, noParams);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ uint32_t PNGImageBufferSize;
+ mContainedEncoder->GetImageBufferUsed(&PNGImageBufferSize);
+ mImageBufferSize =
+ ICONFILEHEADERSIZE + ICODIRENTRYSIZE + PNGImageBufferSize;
+ mImageBufferStart = static_cast<uint8_t*>(malloc(mImageBufferSize));
+ if (!mImageBufferStart) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ mImageBufferCurr = mImageBufferStart;
+ mICODirEntry.mBytesInRes = PNGImageBufferSize;
+
+ EncodeFileHeader();
+ EncodeInfoHeader();
+
+ char* imageBuffer;
+ rv = mContainedEncoder->GetImageBuffer(&imageBuffer);
+ NS_ENSURE_SUCCESS(rv, rv);
+ memcpy(mImageBufferCurr, imageBuffer, PNGImageBufferSize);
+ mImageBufferCurr += PNGImageBufferSize;
+ } else {
+ mContainedEncoder = new nsBMPEncoder();
+ nsresult rv;
+
+ nsAutoString params;
+ params.AppendLiteral("bpp=");
+ params.AppendInt(mICODirEntry.mBitCount);
+
+ rv = mContainedEncoder->InitFromData(aData, aLength, aWidth, aHeight,
+ aStride, aInputFormat, params);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ uint32_t andMaskSize = ((GetRealWidth() + 31) / 32) * 4 * // row AND mask
+ GetRealHeight(); // num rows
+
+ uint32_t BMPImageBufferSize;
+ mContainedEncoder->GetImageBufferUsed(&BMPImageBufferSize);
+ mImageBufferSize =
+ ICONFILEHEADERSIZE + ICODIRENTRYSIZE + BMPImageBufferSize + andMaskSize;
+ mImageBufferStart = static_cast<uint8_t*>(malloc(mImageBufferSize));
+ if (!mImageBufferStart) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ mImageBufferCurr = mImageBufferStart;
+
+ // Icon files that wrap a BMP file must not include the BITMAPFILEHEADER
+ // section at the beginning of the encoded BMP data, so we must skip over
+ // bmp::FILE_HEADER_LENGTH bytes when adding the BMP content to the icon
+ // file.
+ mICODirEntry.mBytesInRes =
+ BMPImageBufferSize - bmp::FILE_HEADER_LENGTH + andMaskSize;
+
+ // Encode the icon headers
+ EncodeFileHeader();
+ EncodeInfoHeader();
+
+ char* imageBuffer;
+ rv = mContainedEncoder->GetImageBuffer(&imageBuffer);
+ NS_ENSURE_SUCCESS(rv, rv);
+ memcpy(mImageBufferCurr, imageBuffer + bmp::FILE_HEADER_LENGTH,
+ BMPImageBufferSize - bmp::FILE_HEADER_LENGTH);
+ // We need to fix the BMP height to be *2 for the AND mask
+ uint32_t fixedHeight = GetRealHeight() * 2;
+ NativeEndian::swapToLittleEndianInPlace(&fixedHeight, 1);
+ // The height is stored at an offset of 8 from the DIB header
+ memcpy(mImageBufferCurr + 8, &fixedHeight, sizeof(fixedHeight));
+ mImageBufferCurr += BMPImageBufferSize - bmp::FILE_HEADER_LENGTH;
+
+ // Calculate rowsize in DWORD's
+ uint32_t rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up
+ int32_t currentLine = GetRealHeight();
+
+ // Write out the AND mask
+ while (currentLine > 0) {
+ currentLine--;
+ uint8_t* encoded = mImageBufferCurr + currentLine * rowSize;
+ uint8_t* encodedEnd = encoded + rowSize;
+ while (encoded != encodedEnd) {
+ *encoded = 0; // make everything visible
+ encoded++;
+ }
+ }
+
+ mImageBufferCurr += andMaskSize;
+ }
+
+ return NS_OK;
+}
+
+// See ::InitFromData for other info.
+NS_IMETHODIMP
+nsICOEncoder::StartImageEncode(uint32_t aWidth, uint32_t aHeight,
+ uint32_t aInputFormat,
+ const nsAString& aOutputOptions) {
+ // can't initialize more than once
+ if (mImageBufferStart || mImageBufferCurr) {
+ return NS_ERROR_ALREADY_INITIALIZED;
+ }
+
+ // validate input format
+ if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA &&
+ aInputFormat != INPUT_FORMAT_HOSTARGB) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // Icons are only 1 byte, so make sure our bitmap is in range
+ if (aWidth > 256 || aHeight > 256) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // parse and check any provided output options
+ uint16_t bpp = 24;
+ bool usePNG = true;
+ nsresult rv = ParseOptions(aOutputOptions, bpp, usePNG);
+ NS_ENSURE_SUCCESS(rv, rv);
+ MOZ_ASSERT(bpp <= 32);
+
+ mUsePNG = usePNG;
+
+ InitFileHeader();
+ // The width and height are stored as 0 when we have a value of 256
+ InitInfoHeader(bpp, aWidth == 256 ? 0 : (uint8_t)aWidth,
+ aHeight == 256 ? 0 : (uint8_t)aHeight);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsICOEncoder::EndImageEncode() {
+ // must be initialized
+ if (!mImageBufferStart || !mImageBufferCurr) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ mFinished = true;
+ NotifyListener();
+
+ // if output callback can't get enough memory, it will free our buffer
+ if (!mImageBufferStart || !mImageBufferCurr) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ return NS_OK;
+}
+
+// Parses the encoder options and sets the bits per pixel to use and PNG or BMP
+// See InitFromData for a description of the parse options
+nsresult nsICOEncoder::ParseOptions(const nsAString& aOptions,
+ uint16_t& aBppOut, bool& aUsePNGOut) {
+ // If no parsing options just use the default of 24BPP and PNG yes
+ if (aOptions.Length() == 0) {
+ aUsePNGOut = true;
+ aBppOut = 24;
+ }
+
+ // Parse the input string into a set of name/value pairs.
+ // From format: format=<png|bmp>;bpp=<bpp_value>
+ // to format: [0] = format=<png|bmp>, [1] = bpp=<bpp_value>
+ nsTArray<nsCString> nameValuePairs;
+ ParseString(NS_ConvertUTF16toUTF8(aOptions), ';', nameValuePairs);
+
+ // For each name/value pair in the set
+ for (unsigned i = 0; i < nameValuePairs.Length(); ++i) {
+ // Split the name value pair [0] = name, [1] = value
+ nsTArray<nsCString> nameValuePair;
+ ParseString(nameValuePairs[i], '=', nameValuePair);
+ if (nameValuePair.Length() != 2) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // Parse the format portion of the string format=<png|bmp>;bpp=<bpp_value>
+ if (nameValuePair[0].Equals("format", nsCaseInsensitiveCStringComparator)) {
+ if (nameValuePair[1].Equals("png", nsCaseInsensitiveCStringComparator)) {
+ aUsePNGOut = true;
+ } else if (nameValuePair[1].Equals("bmp",
+ nsCaseInsensitiveCStringComparator)) {
+ aUsePNGOut = false;
+ } else {
+ return NS_ERROR_INVALID_ARG;
+ }
+ }
+
+ // Parse the bpp portion of the string format=<png|bmp>;bpp=<bpp_value>
+ if (nameValuePair[0].Equals("bpp", nsCaseInsensitiveCStringComparator)) {
+ if (nameValuePair[1].EqualsLiteral("24")) {
+ aBppOut = 24;
+ } else if (nameValuePair[1].EqualsLiteral("32")) {
+ aBppOut = 32;
+ } else {
+ return NS_ERROR_INVALID_ARG;
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsICOEncoder::Close() {
+ if (mImageBufferStart) {
+ free(mImageBufferStart);
+ mImageBufferStart = nullptr;
+ mImageBufferSize = 0;
+ mImageBufferReadPoint = 0;
+ mImageBufferCurr = nullptr;
+ }
+
+ return NS_OK;
+}
+
+// Obtains the available bytes to read
+NS_IMETHODIMP
+nsICOEncoder::Available(uint64_t* _retval) {
+ if (!mImageBufferStart || !mImageBufferCurr) {
+ return NS_BASE_STREAM_CLOSED;
+ }
+
+ *_retval = GetCurrentImageBufferOffset() - mImageBufferReadPoint;
+ return NS_OK;
+}
+
+// Obtains the stream's status
+NS_IMETHODIMP
+nsICOEncoder::StreamStatus() {
+ return mImageBufferStart && mImageBufferCurr ? NS_OK : NS_BASE_STREAM_CLOSED;
+}
+
+// [noscript] Reads bytes which are available
+NS_IMETHODIMP
+nsICOEncoder::Read(char* aBuf, uint32_t aCount, uint32_t* _retval) {
+ return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, _retval);
+}
+
+// [noscript] Reads segments
+NS_IMETHODIMP
+nsICOEncoder::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
+ uint32_t aCount, uint32_t* _retval) {
+ uint32_t maxCount = GetCurrentImageBufferOffset() - mImageBufferReadPoint;
+ if (maxCount == 0) {
+ *_retval = 0;
+ return mFinished ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK;
+ }
+
+ if (aCount > maxCount) {
+ aCount = maxCount;
+ }
+
+ nsresult rv = aWriter(
+ this, aClosure,
+ reinterpret_cast<const char*>(mImageBufferStart + mImageBufferReadPoint),
+ 0, aCount, _retval);
+ if (NS_SUCCEEDED(rv)) {
+ NS_ASSERTION(*_retval <= aCount, "bad write count");
+ mImageBufferReadPoint += *_retval;
+ }
+ // errors returned from the writer end here!
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsICOEncoder::IsNonBlocking(bool* _retval) {
+ *_retval = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsICOEncoder::AsyncWait(nsIInputStreamCallback* aCallback, uint32_t aFlags,
+ uint32_t aRequestedCount, nsIEventTarget* aTarget) {
+ if (aFlags != 0) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+
+ if (mCallback || mCallbackTarget) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ mCallbackTarget = aTarget;
+ // 0 means "any number of bytes except 0"
+ mNotifyThreshold = aRequestedCount;
+ if (!aRequestedCount) {
+ mNotifyThreshold = 1024; // We don't want to notify incessantly
+ }
+
+ // We set the callback absolutely last, because NotifyListener uses it to
+ // determine if someone needs to be notified. If we don't set it last,
+ // NotifyListener might try to fire off a notification to a null target
+ // which will generally cause non-threadsafe objects to be used off the
+ // main thread
+ mCallback = aCallback;
+
+ // What we are being asked for may be present already
+ NotifyListener();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsICOEncoder::CloseWithStatus(nsresult aStatus) { return Close(); }
+
+void nsICOEncoder::NotifyListener() {
+ if (mCallback && (GetCurrentImageBufferOffset() - mImageBufferReadPoint >=
+ mNotifyThreshold ||
+ mFinished)) {
+ nsCOMPtr<nsIInputStreamCallback> callback;
+ if (mCallbackTarget) {
+ callback = NS_NewInputStreamReadyEvent("nsICOEncoder::NotifyListener",
+ mCallback, mCallbackTarget);
+ } else {
+ callback = mCallback;
+ }
+
+ NS_ASSERTION(callback, "Shouldn't fail to make the callback");
+ // Null the callback first because OnInputStreamReady could reenter
+ // AsyncWait
+ mCallback = nullptr;
+ mCallbackTarget = nullptr;
+ mNotifyThreshold = 0;
+
+ callback->OnInputStreamReady(this);
+ }
+}
+
+// Initializes the icon file header mICOFileHeader
+void nsICOEncoder::InitFileHeader() {
+ memset(&mICOFileHeader, 0, sizeof(mICOFileHeader));
+ mICOFileHeader.mReserved = 0;
+ mICOFileHeader.mType = 1;
+ mICOFileHeader.mCount = 1;
+}
+
+// Initializes the icon directory info header mICODirEntry
+void nsICOEncoder::InitInfoHeader(uint16_t aBPP, uint8_t aWidth,
+ uint8_t aHeight) {
+ memset(&mICODirEntry, 0, sizeof(mICODirEntry));
+ mICODirEntry.mBitCount = aBPP;
+ mICODirEntry.mBytesInRes = 0;
+ mICODirEntry.mColorCount = 0;
+ mICODirEntry.mWidth = aWidth;
+ mICODirEntry.mHeight = aHeight;
+ mICODirEntry.mImageOffset = ICONFILEHEADERSIZE + ICODIRENTRYSIZE;
+ mICODirEntry.mPlanes = 1;
+ mICODirEntry.mReserved = 0;
+}
+
+// Encodes the icon file header mICOFileHeader
+void nsICOEncoder::EncodeFileHeader() {
+ IconFileHeader littleEndianIFH = mICOFileHeader;
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianIFH.mReserved, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianIFH.mType, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianIFH.mCount, 1);
+
+ memcpy(mImageBufferCurr, &littleEndianIFH.mReserved,
+ sizeof(littleEndianIFH.mReserved));
+ mImageBufferCurr += sizeof(littleEndianIFH.mReserved);
+ memcpy(mImageBufferCurr, &littleEndianIFH.mType,
+ sizeof(littleEndianIFH.mType));
+ mImageBufferCurr += sizeof(littleEndianIFH.mType);
+ memcpy(mImageBufferCurr, &littleEndianIFH.mCount,
+ sizeof(littleEndianIFH.mCount));
+ mImageBufferCurr += sizeof(littleEndianIFH.mCount);
+}
+
+// Encodes the icon directory info header mICODirEntry
+void nsICOEncoder::EncodeInfoHeader() {
+ IconDirEntry littleEndianmIDE = mICODirEntry;
+
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmIDE.mPlanes, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmIDE.mBitCount, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmIDE.mBytesInRes, 1);
+ NativeEndian::swapToLittleEndianInPlace(&littleEndianmIDE.mImageOffset, 1);
+
+ memcpy(mImageBufferCurr, &littleEndianmIDE.mWidth,
+ sizeof(littleEndianmIDE.mWidth));
+ mImageBufferCurr += sizeof(littleEndianmIDE.mWidth);
+ memcpy(mImageBufferCurr, &littleEndianmIDE.mHeight,
+ sizeof(littleEndianmIDE.mHeight));
+ mImageBufferCurr += sizeof(littleEndianmIDE.mHeight);
+ memcpy(mImageBufferCurr, &littleEndianmIDE.mColorCount,
+ sizeof(littleEndianmIDE.mColorCount));
+ mImageBufferCurr += sizeof(littleEndianmIDE.mColorCount);
+ memcpy(mImageBufferCurr, &littleEndianmIDE.mReserved,
+ sizeof(littleEndianmIDE.mReserved));
+ mImageBufferCurr += sizeof(littleEndianmIDE.mReserved);
+ memcpy(mImageBufferCurr, &littleEndianmIDE.mPlanes,
+ sizeof(littleEndianmIDE.mPlanes));
+ mImageBufferCurr += sizeof(littleEndianmIDE.mPlanes);
+ memcpy(mImageBufferCurr, &littleEndianmIDE.mBitCount,
+ sizeof(littleEndianmIDE.mBitCount));
+ mImageBufferCurr += sizeof(littleEndianmIDE.mBitCount);
+ memcpy(mImageBufferCurr, &littleEndianmIDE.mBytesInRes,
+ sizeof(littleEndianmIDE.mBytesInRes));
+ mImageBufferCurr += sizeof(littleEndianmIDE.mBytesInRes);
+ memcpy(mImageBufferCurr, &littleEndianmIDE.mImageOffset,
+ sizeof(littleEndianmIDE.mImageOffset));
+ mImageBufferCurr += sizeof(littleEndianmIDE.mImageOffset);
+}
diff --git a/image/encoders/ico/nsICOEncoder.h b/image/encoders/ico/nsICOEncoder.h
new file mode 100644
index 0000000000..ef601ba97e
--- /dev/null
+++ b/image/encoders/ico/nsICOEncoder.h
@@ -0,0 +1,95 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_encoders_ico_nsICOEncoder_h
+#define mozilla_image_encoders_ico_nsICOEncoder_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/ReentrantMonitor.h"
+#include "mozilla/image/ICOFileHeaders.h"
+
+#include "imgIEncoder.h"
+
+#include "nsCOMPtr.h"
+
+#define NS_ICOENCODER_CID \
+ { /*92AE3AB2-8968-41B1-8709-B6123BCEAF21 */ \
+ 0x92ae3ab2, 0x8968, 0x41b1, { \
+ 0x87, 0x09, 0xb6, 0x12, 0x3b, 0Xce, 0xaf, 0x21 \
+ } \
+ }
+
+// Provides ICO encoding functionality. Use InitFromData() to do the
+// encoding. See that function definition for encoding options.
+
+class nsICOEncoder final : public imgIEncoder {
+ typedef mozilla::ReentrantMonitor ReentrantMonitor;
+
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_IMGIENCODER
+ NS_DECL_NSIINPUTSTREAM
+ NS_DECL_NSIASYNCINPUTSTREAM
+
+ nsICOEncoder();
+
+ // Obtains the width of the icon directory entry
+ uint32_t GetRealWidth() const {
+ return mICODirEntry.mWidth == 0 ? 256 : mICODirEntry.mWidth;
+ }
+
+ // Obtains the height of the icon directory entry
+ uint32_t GetRealHeight() const {
+ return mICODirEntry.mHeight == 0 ? 256 : mICODirEntry.mHeight;
+ }
+
+ protected:
+ ~nsICOEncoder();
+
+ nsresult ParseOptions(const nsAString& aOptions, uint16_t& aBppOut,
+ bool& aUsePNGOut);
+ void NotifyListener();
+
+ // Initializes the icon file header mICOFileHeader
+ void InitFileHeader();
+ // Initializes the icon directory info header mICODirEntry
+ void InitInfoHeader(uint16_t aBPP, uint8_t aWidth, uint8_t aHeight);
+ // Encodes the icon file header mICOFileHeader
+ void EncodeFileHeader();
+ // Encodes the icon directory info header mICODirEntry
+ void EncodeInfoHeader();
+ // Obtains the current offset filled up to for the image buffer
+ inline int32_t GetCurrentImageBufferOffset() {
+ return static_cast<int32_t>(mImageBufferCurr - mImageBufferStart);
+ }
+
+ // Holds either a PNG or a BMP depending on the encoding options specified
+ // or if no encoding options specified will use the default (PNG)
+ nsCOMPtr<imgIEncoder> mContainedEncoder;
+
+ // These headers will always contain endian independent stuff.
+ // Don't trust the width and height of mICODirEntry directly,
+ // instead use the accessors GetRealWidth() and GetRealHeight().
+ mozilla::image::IconFileHeader mICOFileHeader;
+ mozilla::image::IconDirEntry mICODirEntry;
+
+ // Keeps track of the start of the image buffer
+ uint8_t* mImageBufferStart;
+ // Keeps track of the current position in the image buffer
+ uint8_t* mImageBufferCurr;
+ // Keeps track of the image buffer size
+ uint32_t mImageBufferSize;
+ // Keeps track of the number of bytes in the image buffer which are read
+ uint32_t mImageBufferReadPoint;
+ // Stores true if the image is done being encoded
+ bool mFinished;
+ // Stores true if the contained image is a PNG
+ bool mUsePNG;
+
+ nsCOMPtr<nsIInputStreamCallback> mCallback;
+ nsCOMPtr<nsIEventTarget> mCallbackTarget;
+ uint32_t mNotifyThreshold;
+};
+
+#endif // mozilla_image_encoders_ico_nsICOEncoder_h
diff --git a/image/encoders/jpeg/moz.build b/image/encoders/jpeg/moz.build
new file mode 100644
index 0000000000..6952fc1b9f
--- /dev/null
+++ b/image/encoders/jpeg/moz.build
@@ -0,0 +1,11 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+SOURCES += [
+ "nsJPEGEncoder.cpp",
+]
+
+FINAL_LIBRARY = "xul"
diff --git a/image/encoders/jpeg/nsJPEGEncoder.cpp b/image/encoders/jpeg/nsJPEGEncoder.cpp
new file mode 100644
index 0000000000..2975532b58
--- /dev/null
+++ b/image/encoders/jpeg/nsJPEGEncoder.cpp
@@ -0,0 +1,519 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsJPEGEncoder.h"
+#include "prprf.h"
+#include "nsString.h"
+#include "nsStreamUtils.h"
+#include "gfxColor.h"
+#include "mozilla/CheckedInt.h"
+#include "mozilla/UniquePtrExtensions.h"
+
+extern "C" {
+#include "jpeglib.h"
+}
+
+#include <setjmp.h>
+#include "jerror.h"
+
+using namespace mozilla;
+
+NS_IMPL_ISUPPORTS(nsJPEGEncoder, imgIEncoder, nsIInputStream,
+ nsIAsyncInputStream)
+
+class nsJPEGEncoderInternal {
+ friend class nsJPEGEncoder;
+
+ protected:
+ /**
+ * Initialize destination. This is called by jpeg_start_compress() before
+ * any data is actually written. It must initialize next_output_byte and
+ * free_in_buffer. free_in_buffer must be initialized to a positive value.
+ */
+ static void initDestination(jpeg_compress_struct* cinfo);
+
+ /**
+ * This is called whenever the buffer has filled (free_in_buffer reaches
+ * zero). In typical applications, it should write out the *entire* buffer
+ * (use the saved start address and buffer length; ignore the current state
+ * of next_output_byte and free_in_buffer). Then reset the pointer & count
+ * to the start of the buffer, and return TRUE indicating that the buffer
+ * has been dumped. free_in_buffer must be set to a positive value when
+ * TRUE is returned. A FALSE return should only be used when I/O suspension
+ * is desired (this operating mode is discussed in the next section).
+ */
+ static boolean emptyOutputBuffer(jpeg_compress_struct* cinfo);
+
+ /**
+ * Terminate destination --- called by jpeg_finish_compress() after all data
+ * has been written. In most applications, this must flush any data
+ * remaining in the buffer. Use either next_output_byte or free_in_buffer
+ * to determine how much data is in the buffer.
+ */
+ static void termDestination(jpeg_compress_struct* cinfo);
+
+ /**
+ * Override the standard error method in the IJG JPEG decoder code. This
+ * was mostly copied from nsJPEGDecoder.cpp
+ */
+ static void errorExit(jpeg_common_struct* cinfo);
+};
+
+// used to pass error info through the JPEG library
+struct encoder_error_mgr {
+ jpeg_error_mgr pub;
+ jmp_buf setjmp_buffer;
+};
+
+nsJPEGEncoder::nsJPEGEncoder()
+ : mFinished(false),
+ mImageBuffer(nullptr),
+ mImageBufferSize(0),
+ mImageBufferUsed(0),
+ mImageBufferReadPoint(0),
+ mCallback(nullptr),
+ mCallbackTarget(nullptr),
+ mNotifyThreshold(0),
+ mReentrantMonitor("nsJPEGEncoder.mReentrantMonitor") {}
+
+nsJPEGEncoder::~nsJPEGEncoder() {
+ if (mImageBuffer) {
+ free(mImageBuffer);
+ mImageBuffer = nullptr;
+ }
+}
+
+// nsJPEGEncoder::InitFromData
+//
+// One output option is supported: "quality=X" where X is an integer in the
+// range 0-100. Higher values for X give better quality.
+//
+// Transparency is always discarded.
+
+NS_IMETHODIMP
+nsJPEGEncoder::InitFromData(const uint8_t* aData,
+ uint32_t aLength, // (unused, req'd by JS)
+ uint32_t aWidth, uint32_t aHeight, uint32_t aStride,
+ uint32_t aInputFormat,
+ const nsAString& aOutputOptions) {
+ NS_ENSURE_ARG(aData);
+
+ // validate input format
+ if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA &&
+ aInputFormat != INPUT_FORMAT_HOSTARGB)
+ return NS_ERROR_INVALID_ARG;
+
+ // Stride is the padded width of each row, so it better be longer (I'm afraid
+ // people will not understand what stride means, so check it well)
+ if ((aInputFormat == INPUT_FORMAT_RGB && aStride < aWidth * 3) ||
+ ((aInputFormat == INPUT_FORMAT_RGBA ||
+ aInputFormat == INPUT_FORMAT_HOSTARGB) &&
+ aStride < aWidth * 4)) {
+ NS_WARNING("Invalid stride for InitFromData");
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // can't initialize more than once
+ if (mImageBuffer != nullptr) {
+ return NS_ERROR_ALREADY_INITIALIZED;
+ }
+
+ // options: we only have one option so this is easy
+ int quality = 92;
+ if (aOutputOptions.Length() > 0) {
+ // have options string
+ const nsString qualityPrefix(u"quality="_ns);
+ if (aOutputOptions.Length() > qualityPrefix.Length() &&
+ StringBeginsWith(aOutputOptions, qualityPrefix)) {
+ // have quality string
+ nsCString value = NS_ConvertUTF16toUTF8(
+ Substring(aOutputOptions, qualityPrefix.Length()));
+ int newquality = -1;
+ if (PR_sscanf(value.get(), "%d", &newquality) == 1) {
+ if (newquality >= 0 && newquality <= 100) {
+ quality = newquality;
+ } else {
+ NS_WARNING(
+ "Quality value out of range, should be 0-100,"
+ " using default");
+ }
+ } else {
+ NS_WARNING(
+ "Quality value invalid, should be integer 0-100,"
+ " using default");
+ }
+ } else {
+ return NS_ERROR_INVALID_ARG;
+ }
+ }
+
+ UniquePtr<uint8_t[]> rowptr;
+ if (aInputFormat == INPUT_FORMAT_RGBA ||
+ aInputFormat == INPUT_FORMAT_HOSTARGB) {
+ rowptr = MakeUniqueFallible<uint8_t[]>(aWidth * 3);
+ if (NS_WARN_IF(!rowptr)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ jpeg_compress_struct cinfo;
+
+ // We set up the normal JPEG error routines, then override error_exit.
+ // This must be done before the call to create_compress
+ encoder_error_mgr errmgr;
+ cinfo.err = jpeg_std_error(&errmgr.pub);
+ errmgr.pub.error_exit = nsJPEGEncoderInternal::errorExit;
+ // Establish the setjmp return context for my_error_exit to use.
+ if (setjmp(errmgr.setjmp_buffer)) {
+ // If we get here, the JPEG code has signaled an error.
+ // We need to clean up the JPEG object, close the input file, and return.
+ return NS_ERROR_FAILURE;
+ }
+
+ jpeg_create_compress(&cinfo);
+ cinfo.image_width = aWidth;
+ cinfo.image_height = aHeight;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+ cinfo.data_precision = 8;
+
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, quality, 1); // quality here is 0-100
+ if (quality >= 90) {
+ int i;
+ for (i = 0; i < MAX_COMPONENTS; i++) {
+ cinfo.comp_info[i].h_samp_factor = 1;
+ cinfo.comp_info[i].v_samp_factor = 1;
+ }
+ }
+
+ // set up the destination manager
+ jpeg_destination_mgr destmgr;
+ destmgr.init_destination = nsJPEGEncoderInternal::initDestination;
+ destmgr.empty_output_buffer = nsJPEGEncoderInternal::emptyOutputBuffer;
+ destmgr.term_destination = nsJPEGEncoderInternal::termDestination;
+ cinfo.dest = &destmgr;
+ cinfo.client_data = this;
+
+ jpeg_start_compress(&cinfo, 1);
+
+ // feed it the rows
+ if (aInputFormat == INPUT_FORMAT_RGB) {
+ while (cinfo.next_scanline < cinfo.image_height) {
+ const uint8_t* row = &aData[cinfo.next_scanline * aStride];
+ jpeg_write_scanlines(&cinfo, const_cast<uint8_t**>(&row), 1);
+ }
+ } else if (aInputFormat == INPUT_FORMAT_RGBA) {
+ MOZ_ASSERT(rowptr);
+ uint8_t* row = rowptr.get();
+ while (cinfo.next_scanline < cinfo.image_height) {
+ ConvertRGBARow(&aData[cinfo.next_scanline * aStride], row, aWidth);
+ jpeg_write_scanlines(&cinfo, &row, 1);
+ }
+ } else if (aInputFormat == INPUT_FORMAT_HOSTARGB) {
+ MOZ_ASSERT(rowptr);
+ uint8_t* row = rowptr.get();
+ while (cinfo.next_scanline < cinfo.image_height) {
+ ConvertHostARGBRow(&aData[cinfo.next_scanline * aStride], row, aWidth);
+ jpeg_write_scanlines(&cinfo, &row, 1);
+ }
+ }
+
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+
+ mFinished = true;
+ NotifyListener();
+
+ // if output callback can't get enough memory, it will free our buffer
+ if (!mImageBuffer) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsJPEGEncoder::StartImageEncode(uint32_t aWidth, uint32_t aHeight,
+ uint32_t aInputFormat,
+ const nsAString& aOutputOptions) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+// Returns the number of bytes in the image buffer used.
+NS_IMETHODIMP
+nsJPEGEncoder::GetImageBufferUsed(uint32_t* aOutputSize) {
+ NS_ENSURE_ARG_POINTER(aOutputSize);
+ *aOutputSize = mImageBufferUsed;
+ return NS_OK;
+}
+
+// Returns a pointer to the start of the image buffer
+NS_IMETHODIMP
+nsJPEGEncoder::GetImageBuffer(char** aOutputBuffer) {
+ NS_ENSURE_ARG_POINTER(aOutputBuffer);
+ *aOutputBuffer = reinterpret_cast<char*>(mImageBuffer);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsJPEGEncoder::AddImageFrame(const uint8_t* aData, uint32_t aLength,
+ uint32_t aWidth, uint32_t aHeight,
+ uint32_t aStride, uint32_t aFrameFormat,
+ const nsAString& aFrameOptions) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsJPEGEncoder::EndImageEncode() { return NS_ERROR_NOT_IMPLEMENTED; }
+
+NS_IMETHODIMP
+nsJPEGEncoder::Close() {
+ if (mImageBuffer != nullptr) {
+ free(mImageBuffer);
+ mImageBuffer = nullptr;
+ mImageBufferSize = 0;
+ mImageBufferUsed = 0;
+ mImageBufferReadPoint = 0;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsJPEGEncoder::Available(uint64_t* _retval) {
+ if (!mImageBuffer) {
+ return NS_BASE_STREAM_CLOSED;
+ }
+
+ *_retval = mImageBufferUsed - mImageBufferReadPoint;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsJPEGEncoder::StreamStatus() {
+ return mImageBuffer ? NS_OK : NS_BASE_STREAM_CLOSED;
+}
+
+NS_IMETHODIMP
+nsJPEGEncoder::Read(char* aBuf, uint32_t aCount, uint32_t* _retval) {
+ return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, _retval);
+}
+
+NS_IMETHODIMP
+nsJPEGEncoder::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
+ uint32_t aCount, uint32_t* _retval) {
+ // Avoid another thread reallocing the buffer underneath us
+ ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
+
+ uint32_t maxCount = mImageBufferUsed - mImageBufferReadPoint;
+ if (maxCount == 0) {
+ *_retval = 0;
+ return mFinished ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK;
+ }
+
+ if (aCount > maxCount) {
+ aCount = maxCount;
+ }
+ nsresult rv = aWriter(
+ this, aClosure,
+ reinterpret_cast<const char*>(mImageBuffer + mImageBufferReadPoint), 0,
+ aCount, _retval);
+ if (NS_SUCCEEDED(rv)) {
+ NS_ASSERTION(*_retval <= aCount, "bad write count");
+ mImageBufferReadPoint += *_retval;
+ }
+
+ // errors returned from the writer end here!
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsJPEGEncoder::IsNonBlocking(bool* _retval) {
+ *_retval = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsJPEGEncoder::AsyncWait(nsIInputStreamCallback* aCallback, uint32_t aFlags,
+ uint32_t aRequestedCount, nsIEventTarget* aTarget) {
+ if (aFlags != 0) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+
+ if (mCallback || mCallbackTarget) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ mCallbackTarget = aTarget;
+ // 0 means "any number of bytes except 0"
+ mNotifyThreshold = aRequestedCount;
+ if (!aRequestedCount) {
+ mNotifyThreshold = 1024; // 1 KB seems good. We don't want to
+ // notify incessantly
+ }
+
+ // We set the callback absolutely last, because NotifyListener uses it to
+ // determine if someone needs to be notified. If we don't set it last,
+ // NotifyListener might try to fire off a notification to a null target
+ // which will generally cause non-threadsafe objects to be used off the
+ // main thread
+ mCallback = aCallback;
+
+ // What we are being asked for may be present already
+ NotifyListener();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsJPEGEncoder::CloseWithStatus(nsresult aStatus) { return Close(); }
+
+// nsJPEGEncoder::ConvertHostARGBRow
+//
+// Our colors are stored with premultiplied alphas, but we need
+// an output with no alpha in machine-independent byte order.
+//
+// See gfx/cairo/cairo/src/cairo-png.c
+void nsJPEGEncoder::ConvertHostARGBRow(const uint8_t* aSrc, uint8_t* aDest,
+ uint32_t aPixelWidth) {
+ for (uint32_t x = 0; x < aPixelWidth; x++) {
+ const uint32_t& pixelIn = ((const uint32_t*)(aSrc))[x];
+ uint8_t* pixelOut = &aDest[x * 3];
+
+ pixelOut[0] = (pixelIn & 0xff0000) >> 16;
+ pixelOut[1] = (pixelIn & 0x00ff00) >> 8;
+ pixelOut[2] = (pixelIn & 0x0000ff) >> 0;
+ }
+}
+
+/**
+ * nsJPEGEncoder::ConvertRGBARow
+ *
+ * Input is RGBA, output is RGB, so we should alpha-premultiply.
+ */
+void nsJPEGEncoder::ConvertRGBARow(const uint8_t* aSrc, uint8_t* aDest,
+ uint32_t aPixelWidth) {
+ for (uint32_t x = 0; x < aPixelWidth; x++) {
+ const uint8_t* pixelIn = &aSrc[x * 4];
+ uint8_t* pixelOut = &aDest[x * 3];
+
+ uint8_t alpha = pixelIn[3];
+ pixelOut[0] = gfxPreMultiply(pixelIn[0], alpha);
+ pixelOut[1] = gfxPreMultiply(pixelIn[1], alpha);
+ pixelOut[2] = gfxPreMultiply(pixelIn[2], alpha);
+ }
+}
+
+void nsJPEGEncoder::NotifyListener() {
+ // We might call this function on multiple threads (any threads that call
+ // AsyncWait and any that do encoding) so we lock to avoid notifying the
+ // listener twice about the same data (which generally leads to a truncated
+ // image).
+ ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
+
+ if (mCallback &&
+ (mImageBufferUsed - mImageBufferReadPoint >= mNotifyThreshold ||
+ mFinished)) {
+ nsCOMPtr<nsIInputStreamCallback> callback;
+ if (mCallbackTarget) {
+ callback = NS_NewInputStreamReadyEvent("nsJPEGEncoder::NotifyListener",
+ mCallback, mCallbackTarget);
+ } else {
+ callback = mCallback;
+ }
+
+ NS_ASSERTION(callback, "Shouldn't fail to make the callback");
+ // Null the callback first because OnInputStreamReady could reenter
+ // AsyncWait
+ mCallback = nullptr;
+ mCallbackTarget = nullptr;
+ mNotifyThreshold = 0;
+
+ callback->OnInputStreamReady(this);
+ }
+}
+
+/* static */
+void nsJPEGEncoderInternal::initDestination(jpeg_compress_struct* cinfo) {
+ nsJPEGEncoder* that = static_cast<nsJPEGEncoder*>(cinfo->client_data);
+ NS_ASSERTION(!that->mImageBuffer, "Image buffer already initialized");
+
+ that->mImageBufferSize = 8192;
+ that->mImageBuffer = (uint8_t*)malloc(that->mImageBufferSize);
+ that->mImageBufferUsed = 0;
+
+ cinfo->dest->next_output_byte = that->mImageBuffer;
+ cinfo->dest->free_in_buffer = that->mImageBufferSize;
+}
+
+/* static */
+boolean nsJPEGEncoderInternal::emptyOutputBuffer(jpeg_compress_struct* cinfo) {
+ nsJPEGEncoder* that = static_cast<nsJPEGEncoder*>(cinfo->client_data);
+ NS_ASSERTION(that->mImageBuffer, "No buffer to empty!");
+
+ // When we're reallocing the buffer we need to take the lock to ensure
+ // that nobody is trying to read from the buffer we are destroying
+ ReentrantMonitorAutoEnter autoEnter(that->mReentrantMonitor);
+
+ that->mImageBufferUsed = that->mImageBufferSize;
+
+ // expand buffer, just double size each time
+ uint8_t* newBuf = nullptr;
+ CheckedInt<uint32_t> bufSize =
+ CheckedInt<uint32_t>(that->mImageBufferSize) * 2;
+ if (bufSize.isValid()) {
+ that->mImageBufferSize = bufSize.value();
+ newBuf = (uint8_t*)realloc(that->mImageBuffer, that->mImageBufferSize);
+ }
+
+ if (!newBuf) {
+ // can't resize, just zero (this will keep us from writing more)
+ free(that->mImageBuffer);
+ that->mImageBuffer = nullptr;
+ that->mImageBufferSize = 0;
+ that->mImageBufferUsed = 0;
+
+ // This seems to be the only way to do errors through the JPEG library. We
+ // pass an nsresult masquerading as an int, which works because the
+ // setjmp() caller casts it back.
+ longjmp(((encoder_error_mgr*)(cinfo->err))->setjmp_buffer,
+ static_cast<int>(NS_ERROR_OUT_OF_MEMORY));
+ }
+ that->mImageBuffer = newBuf;
+
+ cinfo->dest->next_output_byte = &that->mImageBuffer[that->mImageBufferUsed];
+ cinfo->dest->free_in_buffer = that->mImageBufferSize - that->mImageBufferUsed;
+ return 1;
+}
+
+/* static */
+void nsJPEGEncoderInternal::termDestination(jpeg_compress_struct* cinfo) {
+ nsJPEGEncoder* that = static_cast<nsJPEGEncoder*>(cinfo->client_data);
+ if (!that->mImageBuffer) {
+ return;
+ }
+ that->mImageBufferUsed = cinfo->dest->next_output_byte - that->mImageBuffer;
+ NS_ASSERTION(that->mImageBufferUsed < that->mImageBufferSize,
+ "JPEG library busted, got a bad image buffer size");
+ that->NotifyListener();
+}
+
+/* static */
+void nsJPEGEncoderInternal::errorExit(jpeg_common_struct* cinfo) {
+ nsresult error_code;
+ encoder_error_mgr* err = (encoder_error_mgr*)cinfo->err;
+
+ // Convert error to a browser error code
+ switch (cinfo->err->msg_code) {
+ case JERR_OUT_OF_MEMORY:
+ error_code = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ default:
+ error_code = NS_ERROR_FAILURE;
+ }
+
+ // Return control to the setjmp point. We pass an nsresult masquerading as
+ // an int, which works because the setjmp() caller casts it back.
+ longjmp(err->setjmp_buffer, static_cast<int>(error_code));
+}
diff --git a/image/encoders/jpeg/nsJPEGEncoder.h b/image/encoders/jpeg/nsJPEGEncoder.h
new file mode 100644
index 0000000000..df543d957b
--- /dev/null
+++ b/image/encoders/jpeg/nsJPEGEncoder.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_encoders_jpeg_nsJPEGEncoder_h
+#define mozilla_image_encoders_jpeg_nsJPEGEncoder_h
+
+#include "imgIEncoder.h"
+
+#include "mozilla/ReentrantMonitor.h"
+#include "mozilla/Attributes.h"
+
+#include "nsCOMPtr.h"
+
+struct jpeg_compress_struct;
+struct jpeg_common_struct;
+
+#define NS_JPEGENCODER_CID \
+ { \
+ /* ac2bb8fe-eeeb-4572-b40f-be03932b56e0 */ \
+ 0xac2bb8fe, 0xeeeb, 0x4572, { \
+ 0xb4, 0x0f, 0xbe, 0x03, 0x93, 0x2b, 0x56, 0xe0 \
+ } \
+ }
+
+// Provides JPEG encoding functionality. Use InitFromData() to do the
+// encoding. See that function definition for encoding options.
+class nsJPEGEncoderInternal;
+
+class nsJPEGEncoder final : public imgIEncoder {
+ friend class nsJPEGEncoderInternal;
+ typedef mozilla::ReentrantMonitor ReentrantMonitor;
+
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_IMGIENCODER
+ NS_DECL_NSIINPUTSTREAM
+ NS_DECL_NSIASYNCINPUTSTREAM
+
+ nsJPEGEncoder();
+
+ private:
+ ~nsJPEGEncoder();
+
+ protected:
+ void ConvertHostARGBRow(const uint8_t* aSrc, uint8_t* aDest,
+ uint32_t aPixelWidth);
+ void ConvertRGBARow(const uint8_t* aSrc, uint8_t* aDest,
+ uint32_t aPixelWidth);
+
+ void NotifyListener();
+
+ bool mFinished;
+
+ // image buffer
+ uint8_t* mImageBuffer;
+ uint32_t mImageBufferSize;
+ uint32_t mImageBufferUsed;
+
+ uint32_t mImageBufferReadPoint;
+
+ nsCOMPtr<nsIInputStreamCallback> mCallback;
+ nsCOMPtr<nsIEventTarget> mCallbackTarget;
+ uint32_t mNotifyThreshold;
+
+ // nsJPEGEncoder is designed to allow one thread to pump data into it while
+ // another reads from it. We lock to ensure that the buffer remains
+ // append-only while we read from it (that it is not realloced) and to ensure
+ // that only one thread dispatches a callback for each call to AsyncWait.
+ ReentrantMonitor mReentrantMonitor MOZ_UNANNOTATED;
+};
+
+#endif // mozilla_image_encoders_jpeg_nsJPEGEncoder_h
diff --git a/image/encoders/moz.build b/image/encoders/moz.build
new file mode 100644
index 0000000000..ecb2aa44e0
--- /dev/null
+++ b/image/encoders/moz.build
@@ -0,0 +1,13 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DIRS += [
+ "ico",
+ "png",
+ "jpeg",
+ "bmp",
+ "webp",
+]
diff --git a/image/encoders/png/moz.build b/image/encoders/png/moz.build
new file mode 100644
index 0000000000..fe26a2368e
--- /dev/null
+++ b/image/encoders/png/moz.build
@@ -0,0 +1,17 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+SOURCES += [
+ "nsPNGEncoder.cpp",
+]
+
+LOCAL_INCLUDES += [
+ "/image",
+]
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+FINAL_LIBRARY = "xul"
diff --git a/image/encoders/png/nsPNGEncoder.cpp b/image/encoders/png/nsPNGEncoder.cpp
new file mode 100644
index 0000000000..f21bab67a6
--- /dev/null
+++ b/image/encoders/png/nsPNGEncoder.cpp
@@ -0,0 +1,820 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ImageLogging.h"
+#include "nsCRT.h"
+#include "nsPNGEncoder.h"
+#include "nsStreamUtils.h"
+#include "nsString.h"
+#include "prprf.h"
+#include "mozilla/CheckedInt.h"
+#include "mozilla/UniquePtrExtensions.h"
+
+using namespace mozilla;
+
+static LazyLogModule sPNGEncoderLog("PNGEncoder");
+
+NS_IMPL_ISUPPORTS(nsPNGEncoder, imgIEncoder, nsIInputStream,
+ nsIAsyncInputStream)
+
+#define DEFAULT_ZLIB_LEVEL 3
+#define DEFAULT_FILTERS PNG_FILTER_SUB
+
+nsPNGEncoder::nsPNGEncoder()
+ : mPNG(nullptr),
+ mPNGinfo(nullptr),
+ mIsAnimation(false),
+ mFinished(false),
+ mImageBuffer(nullptr),
+ mImageBufferSize(0),
+ mImageBufferUsed(0),
+ mImageBufferReadPoint(0),
+ mCallback(nullptr),
+ mCallbackTarget(nullptr),
+ mNotifyThreshold(0),
+ mReentrantMonitor("nsPNGEncoder.mReentrantMonitor") {}
+
+nsPNGEncoder::~nsPNGEncoder() {
+ if (mImageBuffer) {
+ free(mImageBuffer);
+ mImageBuffer = nullptr;
+ }
+ // don't leak if EndImageEncode wasn't called
+ if (mPNG) {
+ png_destroy_write_struct(&mPNG, &mPNGinfo);
+ }
+}
+
+// nsPNGEncoder::InitFromData
+//
+// One output option is supported: "transparency=none" means that the
+// output PNG will not have an alpha channel, even if the input does.
+//
+// Based partially on gfx/cairo/cairo/src/cairo-png.c
+// See also media/libpng/libpng-manual.txt
+
+NS_IMETHODIMP
+nsPNGEncoder::InitFromData(const uint8_t* aData,
+ uint32_t aLength, // (unused, req'd by JS)
+ uint32_t aWidth, uint32_t aHeight, uint32_t aStride,
+ uint32_t aInputFormat,
+ const nsAString& aOutputOptions) {
+ NS_ENSURE_ARG(aData);
+ nsresult rv;
+
+ rv = StartImageEncode(aWidth, aHeight, aInputFormat, aOutputOptions);
+ if (!NS_SUCCEEDED(rv)) {
+ return rv;
+ }
+
+ rv = AddImageFrame(aData, aLength, aWidth, aHeight, aStride, aInputFormat,
+ aOutputOptions);
+ if (!NS_SUCCEEDED(rv)) {
+ return rv;
+ }
+
+ rv = EndImageEncode();
+
+ return rv;
+}
+
+// nsPNGEncoder::StartImageEncode
+//
+//
+// See ::InitFromData for other info.
+NS_IMETHODIMP
+nsPNGEncoder::StartImageEncode(uint32_t aWidth, uint32_t aHeight,
+ uint32_t aInputFormat,
+ const nsAString& aOutputOptions) {
+ bool useTransparency = true, skipFirstFrame = false;
+ uint32_t numFrames = 1;
+ uint32_t numPlays = 0; // For animations, 0 == forever
+ int zlibLevel = DEFAULT_ZLIB_LEVEL;
+ int filters = DEFAULT_FILTERS;
+
+ // can't initialize more than once
+ if (mImageBuffer != nullptr) {
+ return NS_ERROR_ALREADY_INITIALIZED;
+ }
+
+ // validate input format
+ if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA &&
+ aInputFormat != INPUT_FORMAT_HOSTARGB)
+ return NS_ERROR_INVALID_ARG;
+
+ // parse and check any provided output options
+ nsresult rv = ParseOptions(aOutputOptions, &useTransparency, &skipFirstFrame,
+ &numFrames, &numPlays, &zlibLevel, &filters,
+ nullptr, nullptr, nullptr, nullptr, nullptr);
+ if (rv != NS_OK) {
+ return rv;
+ }
+
+#ifdef PNG_APNG_SUPPORTED
+ if (numFrames > 1) {
+ mIsAnimation = true;
+ }
+
+#endif
+
+ // initialize
+ mPNG = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, ErrorCallback,
+ WarningCallback);
+ if (!mPNG) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ mPNGinfo = png_create_info_struct(mPNG);
+ if (!mPNGinfo) {
+ png_destroy_write_struct(&mPNG, nullptr);
+ return NS_ERROR_FAILURE;
+ }
+
+ // libpng's error handler jumps back here upon an error.
+ // Note: It's important that all png_* callers do this, or errors
+ // will result in a corrupt time-warped stack.
+ if (setjmp(png_jmpbuf(mPNG))) {
+ png_destroy_write_struct(&mPNG, &mPNGinfo);
+ return NS_ERROR_FAILURE;
+ }
+
+#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
+ png_set_compression_level(mPNG, zlibLevel);
+#endif
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ png_set_filter(mPNG, PNG_FILTER_TYPE_BASE, filters);
+#endif
+
+ // Set up to read the data into our image buffer, start out with an 8K
+ // estimated size. Note: we don't have to worry about freeing this data
+ // in this function. It will be freed on object destruction.
+ mImageBufferSize = 8192;
+ mImageBuffer = (uint8_t*)malloc(mImageBufferSize);
+ if (!mImageBuffer) {
+ png_destroy_write_struct(&mPNG, &mPNGinfo);
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ mImageBufferUsed = 0;
+
+ // set our callback for libpng to give us the data
+ png_set_write_fn(mPNG, this, WriteCallback, nullptr);
+
+ // include alpha?
+ int colorType;
+ if ((aInputFormat == INPUT_FORMAT_HOSTARGB ||
+ aInputFormat == INPUT_FORMAT_RGBA) &&
+ useTransparency)
+ colorType = PNG_COLOR_TYPE_RGB_ALPHA;
+ else
+ colorType = PNG_COLOR_TYPE_RGB;
+
+ png_set_IHDR(mPNG, mPNGinfo, aWidth, aHeight, 8, colorType,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT);
+
+#ifdef PNG_APNG_SUPPORTED
+ if (mIsAnimation) {
+ png_set_first_frame_is_hidden(mPNG, mPNGinfo, skipFirstFrame);
+ png_set_acTL(mPNG, mPNGinfo, numFrames, numPlays);
+ }
+#endif
+
+ // XXX: support PLTE, gAMA, tRNS, bKGD?
+
+ png_write_info(mPNG, mPNGinfo);
+
+ return NS_OK;
+}
+
+// Returns the number of bytes in the image buffer used.
+NS_IMETHODIMP
+nsPNGEncoder::GetImageBufferUsed(uint32_t* aOutputSize) {
+ NS_ENSURE_ARG_POINTER(aOutputSize);
+ *aOutputSize = mImageBufferUsed;
+ return NS_OK;
+}
+
+// Returns a pointer to the start of the image buffer
+NS_IMETHODIMP
+nsPNGEncoder::GetImageBuffer(char** aOutputBuffer) {
+ NS_ENSURE_ARG_POINTER(aOutputBuffer);
+ *aOutputBuffer = reinterpret_cast<char*>(mImageBuffer);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPNGEncoder::AddImageFrame(const uint8_t* aData,
+ uint32_t aLength, // (unused, req'd by JS)
+ uint32_t aWidth, uint32_t aHeight, uint32_t aStride,
+ uint32_t aInputFormat,
+ const nsAString& aFrameOptions) {
+ bool useTransparency = true;
+ int filters = DEFAULT_FILTERS;
+ uint32_t delay_ms = 500;
+#ifdef PNG_APNG_SUPPORTED
+ uint32_t dispose_op = PNG_DISPOSE_OP_NONE;
+ uint32_t blend_op = PNG_BLEND_OP_SOURCE;
+#else
+ uint32_t dispose_op;
+ uint32_t blend_op;
+#endif
+ uint32_t x_offset = 0, y_offset = 0;
+
+ // must be initialized
+ if (mImageBuffer == nullptr) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ // EndImageEncode was done, or some error occurred earlier
+ if (!mPNG) {
+ return NS_BASE_STREAM_CLOSED;
+ }
+
+ // validate input format
+ if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA &&
+ aInputFormat != INPUT_FORMAT_HOSTARGB)
+ return NS_ERROR_INVALID_ARG;
+
+ // libpng's error handler jumps back here upon an error.
+ if (setjmp(png_jmpbuf(mPNG))) {
+ png_destroy_write_struct(&mPNG, &mPNGinfo);
+ return NS_ERROR_FAILURE;
+ }
+
+ // parse and check any provided output options
+ nsresult rv = ParseOptions(aFrameOptions, &useTransparency, nullptr, nullptr,
+ nullptr, nullptr, &filters, &dispose_op, &blend_op,
+ &delay_ms, &x_offset, &y_offset);
+ if (rv != NS_OK) {
+ return rv;
+ }
+
+#ifdef PNG_APNG_SUPPORTED
+ if (mIsAnimation) {
+ // XXX the row pointers arg (#3) is unused, can it be removed?
+ png_write_frame_head(mPNG, mPNGinfo, nullptr, aWidth, aHeight, x_offset,
+ y_offset, delay_ms, 1000, dispose_op, blend_op);
+ }
+#endif
+
+ // Stride is the padded width of each row, so it better be longer
+ // (I'm afraid people will not understand what stride means, so
+ // check it well)
+ if ((aInputFormat == INPUT_FORMAT_RGB && aStride < aWidth * 3) ||
+ ((aInputFormat == INPUT_FORMAT_RGBA ||
+ aInputFormat == INPUT_FORMAT_HOSTARGB) &&
+ aStride < aWidth * 4)) {
+ NS_WARNING("Invalid stride for InitFromData/AddImageFrame");
+ return NS_ERROR_INVALID_ARG;
+ }
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ png_set_filter(mPNG, PNG_FILTER_TYPE_BASE, filters);
+#endif
+
+ // write each row: if we add more input formats, we may want to
+ // generalize the conversions
+ if (aInputFormat == INPUT_FORMAT_HOSTARGB) {
+ // PNG requires RGBA with post-multiplied alpha, so we need to
+ // convert
+ UniquePtr<uint8_t[]> row = MakeUniqueFallible<uint8_t[]>(aWidth * 4);
+ if (NS_WARN_IF(!row)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ for (uint32_t y = 0; y < aHeight; y++) {
+ ConvertHostARGBRow(&aData[y * aStride], row.get(), aWidth,
+ useTransparency);
+ png_write_row(mPNG, row.get());
+ }
+ } else if (aInputFormat == INPUT_FORMAT_RGBA && !useTransparency) {
+ // RBGA, but we need to strip the alpha
+ UniquePtr<uint8_t[]> row = MakeUniqueFallible<uint8_t[]>(aWidth * 4);
+ if (NS_WARN_IF(!row)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ for (uint32_t y = 0; y < aHeight; y++) {
+ StripAlpha(&aData[y * aStride], row.get(), aWidth);
+ png_write_row(mPNG, row.get());
+ }
+ } else if (aInputFormat == INPUT_FORMAT_RGB ||
+ aInputFormat == INPUT_FORMAT_RGBA) {
+ // simple RBG(A), no conversion needed
+ for (uint32_t y = 0; y < aHeight; y++) {
+ png_write_row(mPNG, (uint8_t*)&aData[y * aStride]);
+ }
+
+ } else {
+ MOZ_ASSERT_UNREACHABLE("Bad format type");
+ return NS_ERROR_INVALID_ARG;
+ }
+
+#ifdef PNG_APNG_SUPPORTED
+ if (mIsAnimation) {
+ png_write_frame_tail(mPNG, mPNGinfo);
+ }
+#endif
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPNGEncoder::EndImageEncode() {
+ // must be initialized
+ if (mImageBuffer == nullptr) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ // EndImageEncode has already been called, or some error
+ // occurred earlier
+ if (!mPNG) {
+ return NS_BASE_STREAM_CLOSED;
+ }
+
+ // libpng's error handler jumps back here upon an error.
+ if (setjmp(png_jmpbuf(mPNG))) {
+ png_destroy_write_struct(&mPNG, &mPNGinfo);
+ return NS_ERROR_FAILURE;
+ }
+
+ png_write_end(mPNG, mPNGinfo);
+ png_destroy_write_struct(&mPNG, &mPNGinfo);
+
+ mFinished = true;
+ NotifyListener();
+
+ // if output callback can't get enough memory, it will free our buffer
+ if (!mImageBuffer) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ return NS_OK;
+}
+
+nsresult nsPNGEncoder::ParseOptions(const nsAString& aOptions,
+ bool* useTransparency, bool* skipFirstFrame,
+ uint32_t* numFrames, uint32_t* numPlays,
+ int* zlibLevel, int* filters,
+ uint32_t* frameDispose,
+ uint32_t* frameBlend, uint32_t* frameDelay,
+ uint32_t* offsetX, uint32_t* offsetY) {
+#ifdef PNG_APNG_SUPPORTED
+ // Make a copy of aOptions, because strtok() will modify it.
+ nsAutoCString optionsCopy;
+ optionsCopy.Assign(NS_ConvertUTF16toUTF8(aOptions));
+ char* options = optionsCopy.BeginWriting();
+
+ while (char* token = nsCRT::strtok(options, ";", &options)) {
+ // If there's an '=' character, split the token around it.
+ char* equals = token;
+ char* value = nullptr;
+ while (*equals != '=' && *equals) {
+ ++equals;
+ }
+ if (*equals == '=') {
+ value = equals + 1;
+ }
+
+ if (value) {
+ *equals = '\0'; // temporary null
+ }
+
+ // transparency=[yes|no|none]
+ if (nsCRT::strcmp(token, "transparency") == 0 && useTransparency) {
+ if (!value) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (nsCRT::strcmp(value, "none") == 0 ||
+ nsCRT::strcmp(value, "no") == 0) {
+ *useTransparency = false;
+ } else if (nsCRT::strcmp(value, "yes") == 0) {
+ *useTransparency = true;
+ } else {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // skipfirstframe=[yes|no]
+ } else if (nsCRT::strcmp(token, "skipfirstframe") == 0 && skipFirstFrame) {
+ if (!value) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (nsCRT::strcmp(value, "no") == 0) {
+ *skipFirstFrame = false;
+ } else if (nsCRT::strcmp(value, "yes") == 0) {
+ *skipFirstFrame = true;
+ } else {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // frames=#
+ } else if (nsCRT::strcmp(token, "frames") == 0 && numFrames) {
+ if (!value) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (PR_sscanf(value, "%u", numFrames) != 1) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // frames=0 is nonsense.
+ if (*numFrames == 0) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // plays=#
+ } else if (nsCRT::strcmp(token, "plays") == 0 && numPlays) {
+ if (!value) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // plays=0 to loop forever, otherwise play sequence specified
+ // number of times
+ if (PR_sscanf(value, "%u", numPlays) != 1) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // png-zlib-level=#
+ } else if (nsCRT::strcmp(token, "png-zlib-level") == 0) {
+ if (!value) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ int localZlibLevel = DEFAULT_ZLIB_LEVEL;
+ if (PR_sscanf(value, "%d", &localZlibLevel) != 1) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // zlib-level 0-9 are the only valid values
+ if (localZlibLevel < 0 || localZlibLevel > 9) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (zlibLevel) {
+ *zlibLevel = localZlibLevel;
+ }
+
+ // png-filter=[no_filters|none|sub|up|avg|paeth|fast|all]
+ } else if (nsCRT::strcmp(token, "png-filter") == 0) {
+ if (!value) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (nsCRT::strcmp(value, "no_filters") == 0) {
+ if (filters) {
+ *filters = PNG_NO_FILTERS;
+ }
+ } else if (nsCRT::strcmp(value, "none") == 0) {
+ if (filters) {
+ *filters = PNG_FILTER_NONE;
+ }
+ } else if (nsCRT::strcmp(value, "sub") == 0) {
+ if (filters) {
+ *filters = PNG_FILTER_SUB;
+ }
+ } else if (nsCRT::strcmp(value, "up") == 0) {
+ if (filters) {
+ *filters = PNG_FILTER_UP;
+ }
+ } else if (nsCRT::strcmp(value, "avg") == 0) {
+ if (filters) {
+ *filters = PNG_FILTER_AVG;
+ }
+ } else if (nsCRT::strcmp(value, "paeth") == 0) {
+ if (filters) {
+ *filters = PNG_FILTER_PAETH;
+ }
+ } else if (nsCRT::strcmp(value, "fast") == 0) {
+ if (filters) {
+ *filters = PNG_FAST_FILTERS;
+ }
+ } else if (nsCRT::strcmp(value, "all") == 0) {
+ if (filters) {
+ *filters = PNG_ALL_FILTERS;
+ }
+ } else {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // dispose=[none|background|previous]
+ } else if (nsCRT::strcmp(token, "dispose") == 0 && frameDispose) {
+ if (!value) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (nsCRT::strcmp(value, "none") == 0) {
+ *frameDispose = PNG_DISPOSE_OP_NONE;
+ } else if (nsCRT::strcmp(value, "background") == 0) {
+ *frameDispose = PNG_DISPOSE_OP_BACKGROUND;
+ } else if (nsCRT::strcmp(value, "previous") == 0) {
+ *frameDispose = PNG_DISPOSE_OP_PREVIOUS;
+ } else {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // blend=[source|over]
+ } else if (nsCRT::strcmp(token, "blend") == 0 && frameBlend) {
+ if (!value) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (nsCRT::strcmp(value, "source") == 0) {
+ *frameBlend = PNG_BLEND_OP_SOURCE;
+ } else if (nsCRT::strcmp(value, "over") == 0) {
+ *frameBlend = PNG_BLEND_OP_OVER;
+ } else {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // delay=# (in ms)
+ } else if (nsCRT::strcmp(token, "delay") == 0 && frameDelay) {
+ if (!value) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (PR_sscanf(value, "%u", frameDelay) != 1) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // xoffset=#
+ } else if (nsCRT::strcmp(token, "xoffset") == 0 && offsetX) {
+ if (!value) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (PR_sscanf(value, "%u", offsetX) != 1) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // yoffset=#
+ } else if (nsCRT::strcmp(token, "yoffset") == 0 && offsetY) {
+ if (!value) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (PR_sscanf(value, "%u", offsetY) != 1) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // unknown token name
+ } else
+ return NS_ERROR_INVALID_ARG;
+
+ if (value) {
+ *equals = '='; // restore '=' so strtok doesn't get lost
+ }
+ }
+
+#endif
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPNGEncoder::Close() {
+ if (mImageBuffer != nullptr) {
+ free(mImageBuffer);
+ mImageBuffer = nullptr;
+ mImageBufferSize = 0;
+ mImageBufferUsed = 0;
+ mImageBufferReadPoint = 0;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPNGEncoder::Available(uint64_t* _retval) {
+ if (!mImageBuffer) {
+ return NS_BASE_STREAM_CLOSED;
+ }
+
+ *_retval = mImageBufferUsed - mImageBufferReadPoint;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPNGEncoder::StreamStatus() {
+ return mImageBuffer ? NS_OK : NS_BASE_STREAM_CLOSED;
+}
+
+NS_IMETHODIMP
+nsPNGEncoder::Read(char* aBuf, uint32_t aCount, uint32_t* _retval) {
+ return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, _retval);
+}
+
+NS_IMETHODIMP
+nsPNGEncoder::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
+ uint32_t aCount, uint32_t* _retval) {
+ // Avoid another thread reallocing the buffer underneath us
+ ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
+
+ uint32_t maxCount = mImageBufferUsed - mImageBufferReadPoint;
+ if (maxCount == 0) {
+ *_retval = 0;
+ return mFinished ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK;
+ }
+
+ if (aCount > maxCount) {
+ aCount = maxCount;
+ }
+
+ nsresult rv = aWriter(
+ this, aClosure,
+ reinterpret_cast<const char*>(mImageBuffer + mImageBufferReadPoint), 0,
+ aCount, _retval);
+ if (NS_SUCCEEDED(rv)) {
+ NS_ASSERTION(*_retval <= aCount, "bad write count");
+ mImageBufferReadPoint += *_retval;
+ }
+
+ // errors returned from the writer end here!
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPNGEncoder::IsNonBlocking(bool* _retval) {
+ *_retval = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPNGEncoder::AsyncWait(nsIInputStreamCallback* aCallback, uint32_t aFlags,
+ uint32_t aRequestedCount, nsIEventTarget* aTarget) {
+ if (aFlags != 0) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+
+ if (mCallback || mCallbackTarget) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ mCallbackTarget = aTarget;
+ // 0 means "any number of bytes except 0"
+ mNotifyThreshold = aRequestedCount;
+ if (!aRequestedCount) {
+ mNotifyThreshold = 1024; // We don't want to notify incessantly
+ }
+
+ // We set the callback absolutely last, because NotifyListener uses it to
+ // determine if someone needs to be notified. If we don't set it last,
+ // NotifyListener might try to fire off a notification to a null target
+ // which will generally cause non-threadsafe objects to be used off the main
+ // thread
+ mCallback = aCallback;
+
+ // What we are being asked for may be present already
+ NotifyListener();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPNGEncoder::CloseWithStatus(nsresult aStatus) { return Close(); }
+
+// nsPNGEncoder::ConvertHostARGBRow
+//
+// Our colors are stored with premultiplied alphas, but PNGs use
+// post-multiplied alpha. This swaps to PNG-style alpha.
+//
+// Copied from gfx/cairo/cairo/src/cairo-png.c
+
+void nsPNGEncoder::ConvertHostARGBRow(const uint8_t* aSrc, uint8_t* aDest,
+ uint32_t aPixelWidth,
+ bool aUseTransparency) {
+ uint32_t pixelStride = aUseTransparency ? 4 : 3;
+ for (uint32_t x = 0; x < aPixelWidth; x++) {
+ const uint32_t& pixelIn = ((const uint32_t*)(aSrc))[x];
+ uint8_t* pixelOut = &aDest[x * pixelStride];
+
+ uint8_t alpha = (pixelIn & 0xff000000) >> 24;
+ pixelOut[pixelStride - 1] = alpha; // overwritten below if pixelStride == 3
+ if (alpha == 255) {
+ pixelOut[0] = (pixelIn & 0xff0000) >> 16;
+ pixelOut[1] = (pixelIn & 0x00ff00) >> 8;
+ pixelOut[2] = (pixelIn & 0x0000ff);
+ } else if (alpha == 0) {
+ pixelOut[0] = pixelOut[1] = pixelOut[2] = 0;
+ } else {
+ pixelOut[0] = (((pixelIn & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
+ pixelOut[1] = (((pixelIn & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
+ pixelOut[2] = (((pixelIn & 0x0000ff)) * 255 + alpha / 2) / alpha;
+ }
+ }
+}
+
+// nsPNGEncoder::StripAlpha
+//
+// Input is RGBA, output is RGB
+
+void nsPNGEncoder::StripAlpha(const uint8_t* aSrc, uint8_t* aDest,
+ uint32_t aPixelWidth) {
+ for (uint32_t x = 0; x < aPixelWidth; x++) {
+ const uint8_t* pixelIn = &aSrc[x * 4];
+ uint8_t* pixelOut = &aDest[x * 3];
+ pixelOut[0] = pixelIn[0];
+ pixelOut[1] = pixelIn[1];
+ pixelOut[2] = pixelIn[2];
+ }
+}
+
+// nsPNGEncoder::WarningCallback
+
+void nsPNGEncoder::WarningCallback(png_structp png_ptr,
+ png_const_charp warning_msg) {
+ MOZ_LOG(sPNGEncoderLog, LogLevel::Warning,
+ ("libpng warning: %s\n", warning_msg));
+}
+
+// nsPNGEncoder::ErrorCallback
+
+void nsPNGEncoder::ErrorCallback(png_structp png_ptr,
+ png_const_charp error_msg) {
+ MOZ_LOG(sPNGEncoderLog, LogLevel::Error, ("libpng error: %s\n", error_msg));
+ png_longjmp(png_ptr, 1);
+}
+
+// nsPNGEncoder::WriteCallback
+
+void // static
+nsPNGEncoder::WriteCallback(png_structp png, png_bytep data, png_size_t size) {
+ nsPNGEncoder* that = static_cast<nsPNGEncoder*>(png_get_io_ptr(png));
+ if (!that->mImageBuffer) {
+ return;
+ }
+
+ CheckedUint32 sizeNeeded = CheckedUint32(that->mImageBufferUsed) + size;
+ if (!sizeNeeded.isValid()) {
+ // Take the lock to ensure that nobody is trying to read from the buffer
+ // we are destroying
+ ReentrantMonitorAutoEnter autoEnter(that->mReentrantMonitor);
+
+ that->NullOutImageBuffer();
+ return;
+ }
+
+ if (sizeNeeded.value() > that->mImageBufferSize) {
+ // When we're reallocing the buffer we need to take the lock to ensure
+ // that nobody is trying to read from the buffer we are destroying
+ ReentrantMonitorAutoEnter autoEnter(that->mReentrantMonitor);
+
+ while (sizeNeeded.value() > that->mImageBufferSize) {
+ // expand buffer, just double each time
+ CheckedUint32 bufferSize = CheckedUint32(that->mImageBufferSize) * 2;
+ if (!bufferSize.isValid()) {
+ that->NullOutImageBuffer();
+ return;
+ }
+ that->mImageBufferSize *= 2;
+ uint8_t* newBuf =
+ (uint8_t*)realloc(that->mImageBuffer, that->mImageBufferSize);
+ if (!newBuf) {
+ // can't resize, just zero (this will keep us from writing more)
+ that->NullOutImageBuffer();
+ return;
+ }
+ that->mImageBuffer = newBuf;
+ }
+ }
+
+ memcpy(&that->mImageBuffer[that->mImageBufferUsed], data, size);
+ that->mImageBufferUsed += size;
+ that->NotifyListener();
+}
+
+void nsPNGEncoder::NullOutImageBuffer() {
+ mReentrantMonitor.AssertCurrentThreadIn();
+
+ free(mImageBuffer);
+ mImageBuffer = nullptr;
+ mImageBufferSize = 0;
+ mImageBufferUsed = 0;
+}
+
+void nsPNGEncoder::NotifyListener() {
+ // We might call this function on multiple threads (any threads that call
+ // AsyncWait and any that do encoding) so we lock to avoid notifying the
+ // listener twice about the same data (which generally leads to a truncated
+ // image).
+ ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
+
+ if (mCallback &&
+ (mImageBufferUsed - mImageBufferReadPoint >= mNotifyThreshold ||
+ mFinished)) {
+ nsCOMPtr<nsIInputStreamCallback> callback;
+ if (mCallbackTarget) {
+ callback = NS_NewInputStreamReadyEvent("nsPNGEncoder::NotifyListener",
+ mCallback, mCallbackTarget);
+ } else {
+ callback = mCallback;
+ }
+
+ NS_ASSERTION(callback, "Shouldn't fail to make the callback");
+ // Null the callback first because OnInputStreamReady could reenter
+ // AsyncWait
+ mCallback = nullptr;
+ mCallbackTarget = nullptr;
+ mNotifyThreshold = 0;
+
+ callback->OnInputStreamReady(this);
+ }
+}
diff --git a/image/encoders/png/nsPNGEncoder.h b/image/encoders/png/nsPNGEncoder.h
new file mode 100644
index 0000000000..76d695ccfa
--- /dev/null
+++ b/image/encoders/png/nsPNGEncoder.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_encoders_png_nsPNGEncoder_h
+#define mozilla_image_encoders_png_nsPNGEncoder_h
+
+#include <png.h>
+
+#include "imgIEncoder.h"
+#include "nsCOMPtr.h"
+
+#include "mozilla/Attributes.h"
+#include "mozilla/ReentrantMonitor.h"
+
+#define NS_PNGENCODER_CID \
+ { /* 38d1592e-b81e-432b-86f8-471878bbfe07 */ \
+ 0x38d1592e, 0xb81e, 0x432b, { \
+ 0x86, 0xf8, 0x47, 0x18, 0x78, 0xbb, 0xfe, 0x07 \
+ } \
+ }
+
+// Provides PNG encoding functionality. Use InitFromData() to do the
+// encoding. See that function definition for encoding options.
+
+class nsPNGEncoder final : public imgIEncoder {
+ typedef mozilla::ReentrantMonitor ReentrantMonitor;
+
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_IMGIENCODER
+ NS_DECL_NSIINPUTSTREAM
+ NS_DECL_NSIASYNCINPUTSTREAM
+
+ nsPNGEncoder();
+
+ protected:
+ ~nsPNGEncoder();
+ nsresult ParseOptions(const nsAString& aOptions, bool* useTransparency,
+ bool* skipFirstFrame, uint32_t* numAnimatedFrames,
+ uint32_t* numIterations, int* zlibLevel, int* filters,
+ uint32_t* frameDispose, uint32_t* frameBlend,
+ uint32_t* frameDelay, uint32_t* offsetX,
+ uint32_t* offsetY);
+ void ConvertHostARGBRow(const uint8_t* aSrc, uint8_t* aDest,
+ uint32_t aPixelWidth, bool aUseTransparency);
+ void StripAlpha(const uint8_t* aSrc, uint8_t* aDest, uint32_t aPixelWidth);
+ static void WarningCallback(png_structp png_ptr, png_const_charp warning_msg);
+ static void ErrorCallback(png_structp png_ptr, png_const_charp error_msg);
+ static void WriteCallback(png_structp png, png_bytep data, png_size_t size);
+ void NullOutImageBuffer();
+ void NotifyListener();
+
+ png_struct* mPNG;
+ png_info* mPNGinfo;
+
+ bool mIsAnimation;
+ bool mFinished;
+
+ // image buffer
+ uint8_t* mImageBuffer;
+ uint32_t mImageBufferSize;
+ uint32_t mImageBufferUsed;
+
+ uint32_t mImageBufferReadPoint;
+
+ nsCOMPtr<nsIInputStreamCallback> mCallback;
+ nsCOMPtr<nsIEventTarget> mCallbackTarget;
+ uint32_t mNotifyThreshold;
+
+ // nsPNGEncoder is designed to allow one thread to pump data into it while
+ // another reads from it. We lock to ensure that the buffer remains
+ // append-only while we read from it (that it is not realloced) and to
+ // ensure that only one thread dispatches a callback for each call to
+ // AsyncWait.
+ ReentrantMonitor mReentrantMonitor MOZ_UNANNOTATED;
+};
+#endif // mozilla_image_encoders_png_nsPNGEncoder_h
diff --git a/image/encoders/webp/moz.build b/image/encoders/webp/moz.build
new file mode 100644
index 0000000000..4363caa79f
--- /dev/null
+++ b/image/encoders/webp/moz.build
@@ -0,0 +1,15 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+SOURCES += [
+ "nsWebPEncoder.cpp",
+]
+
+LOCAL_INCLUDES += [
+ "/image",
+]
+
+FINAL_LIBRARY = "xul"
diff --git a/image/encoders/webp/nsWebPEncoder.cpp b/image/encoders/webp/nsWebPEncoder.cpp
new file mode 100644
index 0000000000..72ac1388e9
--- /dev/null
+++ b/image/encoders/webp/nsWebPEncoder.cpp
@@ -0,0 +1,342 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// #include "ImageLogging.h"
+#include "nsCRT.h"
+#include "nsWebPEncoder.h"
+#include "nsStreamUtils.h"
+#include "nsString.h"
+#include "prprf.h"
+#include "mozilla/CheckedInt.h"
+#include "mozilla/UniquePtrExtensions.h"
+
+using namespace mozilla;
+
+// static LazyLogModule sWEBPEncoderLog("WEBPEncoder");
+
+NS_IMPL_ISUPPORTS(nsWebPEncoder, imgIEncoder, nsIInputStream,
+ nsIAsyncInputStream)
+
+nsWebPEncoder::nsWebPEncoder()
+ : mFinished(false),
+ mImageBuffer(nullptr),
+ mImageBufferSize(0),
+ mImageBufferUsed(0),
+ mImageBufferReadPoint(0),
+ mCallback(nullptr),
+ mCallbackTarget(nullptr),
+ mNotifyThreshold(0),
+ mReentrantMonitor("nsWebPEncoder.mReentrantMonitor") {}
+
+nsWebPEncoder::~nsWebPEncoder() {
+ if (mImageBuffer) {
+ WebPFree(mImageBuffer);
+ mImageBuffer = nullptr;
+ mImageBufferSize = 0;
+ mImageBufferUsed = 0;
+ mImageBufferReadPoint = 0;
+ }
+}
+
+// nsWebPEncoder::InitFromData
+//
+// One output option is supported: "quality=X" where X is an integer in the
+// range 0-100. Higher values for X give better quality.
+
+NS_IMETHODIMP
+nsWebPEncoder::InitFromData(const uint8_t* aData,
+ uint32_t aLength, // (unused, req'd by JS)
+ uint32_t aWidth, uint32_t aHeight, uint32_t aStride,
+ uint32_t aInputFormat,
+ const nsAString& aOutputOptions) {
+ NS_ENSURE_ARG(aData);
+
+ // validate input format
+ if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA &&
+ aInputFormat != INPUT_FORMAT_HOSTARGB)
+ return NS_ERROR_INVALID_ARG;
+
+ // Stride is the padded width of each row, so it better be longer (I'm afraid
+ // people will not understand what stride means, so check it well)
+ if ((aInputFormat == INPUT_FORMAT_RGB && aStride < aWidth * 3) ||
+ ((aInputFormat == INPUT_FORMAT_RGBA ||
+ aInputFormat == INPUT_FORMAT_HOSTARGB) &&
+ aStride < aWidth * 4)) {
+ NS_WARNING("Invalid stride for InitFromData");
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // can't initialize more than once
+ if (mImageBuffer != nullptr) {
+ return NS_ERROR_ALREADY_INITIALIZED;
+ }
+
+ // options: we only have one option so this is easy
+ int quality = 92;
+ if (aOutputOptions.Length() > 0) {
+ // have options string
+ const nsString qualityPrefix(u"quality="_ns);
+ if (aOutputOptions.Length() > qualityPrefix.Length() &&
+ StringBeginsWith(aOutputOptions, qualityPrefix)) {
+ // have quality string
+ nsCString value = NS_ConvertUTF16toUTF8(
+ Substring(aOutputOptions, qualityPrefix.Length()));
+ int newquality = -1;
+ if (PR_sscanf(value.get(), "%d", &newquality) == 1) {
+ if (newquality >= 0 && newquality <= 100) {
+ quality = newquality;
+ } else {
+ NS_WARNING(
+ "Quality value out of range, should be 0-100,"
+ " using default");
+ }
+ } else {
+ NS_WARNING(
+ "Quality value invalid, should be integer 0-100,"
+ " using default");
+ }
+ } else {
+ return NS_ERROR_INVALID_ARG;
+ }
+ }
+
+ size_t size = 0;
+
+ CheckedInt32 width = CheckedInt32(aWidth);
+ CheckedInt32 height = CheckedInt32(aHeight);
+ CheckedInt32 stride = CheckedInt32(aStride);
+ if (!width.isValid() || !height.isValid() || !stride.isValid() ||
+ !(CheckedUint32(aStride) * CheckedUint32(aHeight)).isValid()) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (aInputFormat == INPUT_FORMAT_RGB) {
+ size = quality == 100
+ ? WebPEncodeLosslessRGB(aData, width.value(), height.value(),
+ stride.value(), &mImageBuffer)
+ : WebPEncodeRGB(aData, width.value(), height.value(),
+ stride.value(), quality, &mImageBuffer);
+ } else if (aInputFormat == INPUT_FORMAT_RGBA) {
+ size = quality == 100
+ ? WebPEncodeLosslessRGBA(aData, width.value(), height.value(),
+ stride.value(), &mImageBuffer)
+ : WebPEncodeRGBA(aData, width.value(), height.value(),
+ stride.value(), quality, &mImageBuffer);
+ } else if (aInputFormat == INPUT_FORMAT_HOSTARGB) {
+ UniquePtr<uint8_t[]> aDest =
+ MakeUniqueFallible<uint8_t[]>(aStride * aHeight);
+ if (NS_WARN_IF(!aDest)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ for (uint32_t y = 0; y < aHeight; y++) {
+ for (uint32_t x = 0; x < aWidth; x++) {
+ const uint32_t& pixelIn =
+ ((const uint32_t*)(aData))[y * aStride / 4 + x];
+ uint8_t* pixelOut = &aDest[y * aStride + x * 4];
+
+ uint8_t alpha = (pixelIn & 0xff000000) >> 24;
+ pixelOut[3] = alpha;
+ if (alpha == 255) {
+ pixelOut[0] = (pixelIn & 0xff0000) >> 16;
+ pixelOut[1] = (pixelIn & 0x00ff00) >> 8;
+ pixelOut[2] = (pixelIn & 0x0000ff);
+ } else if (alpha == 0) {
+ pixelOut[0] = pixelOut[1] = pixelOut[2] = 0;
+ } else {
+ pixelOut[0] =
+ (((pixelIn & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
+ pixelOut[1] = (((pixelIn & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
+ pixelOut[2] = (((pixelIn & 0x0000ff)) * 255 + alpha / 2) / alpha;
+ }
+ }
+ }
+
+ size =
+ quality == 100
+ ? WebPEncodeLosslessRGBA(aDest.get(), width.value(), height.value(),
+ stride.value(), &mImageBuffer)
+ : WebPEncodeRGBA(aDest.get(), width.value(), height.value(),
+ stride.value(), quality, &mImageBuffer);
+ }
+
+ mFinished = true;
+
+ if (size == 0) {
+ return NS_ERROR_FAILURE;
+ }
+
+ mImageBufferUsed = size;
+
+ return NS_OK;
+}
+
+// nsWebPEncoder::StartImageEncode
+//
+//
+// See ::InitFromData for other info.
+NS_IMETHODIMP
+nsWebPEncoder::StartImageEncode(uint32_t aWidth, uint32_t aHeight,
+ uint32_t aInputFormat,
+ const nsAString& aOutputOptions) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+// Returns the number of bytes in the image buffer used.
+NS_IMETHODIMP
+nsWebPEncoder::GetImageBufferUsed(uint32_t* aOutputSize) {
+ NS_ENSURE_ARG_POINTER(aOutputSize);
+ *aOutputSize = mImageBufferUsed;
+ return NS_OK;
+}
+
+// Returns a pointer to the start of the image buffer
+NS_IMETHODIMP
+nsWebPEncoder::GetImageBuffer(char** aOutputBuffer) {
+ NS_ENSURE_ARG_POINTER(aOutputBuffer);
+ *aOutputBuffer = reinterpret_cast<char*>(mImageBuffer);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebPEncoder::AddImageFrame(const uint8_t* aData,
+ uint32_t aLength, // (unused, req'd by JS)
+ uint32_t aWidth, uint32_t aHeight,
+ uint32_t aStride, uint32_t aInputFormat,
+ const nsAString& aFrameOptions) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsWebPEncoder::EndImageEncode() { return NS_ERROR_NOT_IMPLEMENTED; }
+
+NS_IMETHODIMP
+nsWebPEncoder::Close() {
+ if (mImageBuffer) {
+ WebPFree(mImageBuffer);
+ mImageBuffer = nullptr;
+ mImageBufferSize = 0;
+ mImageBufferUsed = 0;
+ mImageBufferReadPoint = 0;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebPEncoder::Available(uint64_t* _retval) {
+ if (!mImageBuffer) {
+ return NS_BASE_STREAM_CLOSED;
+ }
+
+ *_retval = mImageBufferUsed - mImageBufferReadPoint;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebPEncoder::StreamStatus() {
+ return mImageBuffer ? NS_OK : NS_BASE_STREAM_CLOSED;
+}
+
+NS_IMETHODIMP
+nsWebPEncoder::Read(char* aBuf, uint32_t aCount, uint32_t* _retval) {
+ return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, _retval);
+}
+
+NS_IMETHODIMP
+nsWebPEncoder::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
+ uint32_t aCount, uint32_t* _retval) {
+ // Avoid another thread reallocing the buffer underneath us
+ ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
+
+ uint32_t maxCount = mImageBufferUsed - mImageBufferReadPoint;
+ if (maxCount == 0) {
+ *_retval = 0;
+ return mFinished ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK;
+ }
+
+ if (aCount > maxCount) {
+ aCount = maxCount;
+ }
+ nsresult rv = aWriter(
+ this, aClosure,
+ reinterpret_cast<const char*>(mImageBuffer + mImageBufferReadPoint), 0,
+ aCount, _retval);
+ if (NS_SUCCEEDED(rv)) {
+ NS_ASSERTION(*_retval <= aCount, "bad write count");
+ mImageBufferReadPoint += *_retval;
+ }
+
+ // errors returned from the writer end here!
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebPEncoder::IsNonBlocking(bool* _retval) {
+ *_retval = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebPEncoder::AsyncWait(nsIInputStreamCallback* aCallback, uint32_t aFlags,
+ uint32_t aRequestedCount, nsIEventTarget* aTarget) {
+ if (aFlags != 0) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+
+ if (mCallback || mCallbackTarget) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ mCallbackTarget = aTarget;
+ // 0 means "any number of bytes except 0"
+ mNotifyThreshold = aRequestedCount;
+ if (!aRequestedCount) {
+ mNotifyThreshold = 1024; // 1 KB seems good. We don't want to
+ // notify incessantly
+ }
+
+ // We set the callback absolutely last, because NotifyListener uses it to
+ // determine if someone needs to be notified. If we don't set it last,
+ // NotifyListener might try to fire off a notification to a null target
+ // which will generally cause non-threadsafe objects to be used off the
+ // main thread
+ mCallback = aCallback;
+
+ // What we are being asked for may be present already
+ NotifyListener();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWebPEncoder::CloseWithStatus(nsresult aStatus) { return Close(); }
+
+void nsWebPEncoder::NotifyListener() {
+ // We might call this function on multiple threads (any threads that call
+ // AsyncWait and any that do encoding) so we lock to avoid notifying the
+ // listener twice about the same data (which generally leads to a truncated
+ // image).
+ ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
+
+ if (mCallback &&
+ (mImageBufferUsed - mImageBufferReadPoint >= mNotifyThreshold ||
+ mFinished)) {
+ nsCOMPtr<nsIInputStreamCallback> callback;
+ if (mCallbackTarget) {
+ callback = NS_NewInputStreamReadyEvent("nsWebPEncoder::NotifyListener",
+ mCallback, mCallbackTarget);
+ } else {
+ callback = mCallback;
+ }
+
+ NS_ASSERTION(callback, "Shouldn't fail to make the callback");
+ // Null the callback first because OnInputStreamReady could reenter
+ // AsyncWait
+ mCallback = nullptr;
+ mCallbackTarget = nullptr;
+ mNotifyThreshold = 0;
+
+ callback->OnInputStreamReady(this);
+ }
+}
diff --git a/image/encoders/webp/nsWebPEncoder.h b/image/encoders/webp/nsWebPEncoder.h
new file mode 100644
index 0000000000..8628d12388
--- /dev/null
+++ b/image/encoders/webp/nsWebPEncoder.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_encoders_webp_nsWebPEncoder_h
+#define mozilla_image_encoders_webp_nsWebPEncoder_h
+
+#include "webp/encode.h"
+
+#include "imgIEncoder.h"
+#include "nsCOMPtr.h"
+
+#include "mozilla/Attributes.h"
+#include "mozilla/ReentrantMonitor.h"
+
+#define NS_WEBPENCODER_CID \
+ { /* a8e5a8e5-bebf-4512-9f50-e41e4748ce28 */ \
+ 0xa8e5a8e5, 0xbebf, 0x4512, { \
+ 0x9f, 0x50, 0xe4, 0x1e, 0x47, 0x48, 0xce, 0x28 \
+ } \
+ }
+
+// Provides WEBP encoding functionality. Use InitFromData() to do the
+// encoding. See that function definition for encoding options.
+
+class nsWebPEncoder final : public imgIEncoder {
+ typedef mozilla::ReentrantMonitor ReentrantMonitor;
+
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_IMGIENCODER
+ NS_DECL_NSIINPUTSTREAM
+ NS_DECL_NSIASYNCINPUTSTREAM
+
+ nsWebPEncoder();
+
+ protected:
+ ~nsWebPEncoder();
+
+ void NotifyListener();
+
+ bool mFinished;
+
+ // image buffer
+ uint8_t* mImageBuffer;
+ uint32_t mImageBufferSize;
+ uint32_t mImageBufferUsed;
+
+ uint32_t mImageBufferReadPoint;
+
+ nsCOMPtr<nsIInputStreamCallback> mCallback;
+ nsCOMPtr<nsIEventTarget> mCallbackTarget;
+ uint32_t mNotifyThreshold;
+
+ // nsWebPEncoder is designed to allow one thread to pump data into it while
+ // another reads from it. We lock to ensure that the buffer remains
+ // append-only while we read from it (that it is not realloced) and to
+ // ensure that only one thread dispatches a callback for each call to
+ // AsyncWait.
+ ReentrantMonitor mReentrantMonitor MOZ_UNANNOTATED;
+};
+#endif // mozilla_image_encoders_webp_nsWebPEncoder_h
diff --git a/image/imgFrame.cpp b/image/imgFrame.cpp
new file mode 100644
index 0000000000..0df40fcfa9
--- /dev/null
+++ b/image/imgFrame.cpp
@@ -0,0 +1,729 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "imgFrame.h"
+#include "ImageRegion.h"
+#include "SurfaceCache.h"
+
+#include "prenv.h"
+
+#include "gfx2DGlue.h"
+#include "gfxContext.h"
+#include "gfxPlatform.h"
+
+#include "gfxUtils.h"
+
+#include "MainThreadUtils.h"
+#include "mozilla/CheckedInt.h"
+#include "mozilla/gfx/Tools.h"
+#include "mozilla/Likely.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/ProfilerLabels.h"
+#include "mozilla/StaticPrefs_browser.h"
+#include "nsMargin.h"
+#include "nsRefreshDriver.h"
+#include "nsThreadUtils.h"
+
+#include <algorithm> // for min, max
+
+namespace mozilla {
+
+using namespace gfx;
+
+namespace image {
+
+/**
+ * This class is identical to SourceSurfaceSharedData but returns a different
+ * type so that SharedSurfacesChild is aware imagelib wants to recycle this
+ * surface for future animation frames.
+ */
+class RecyclingSourceSurfaceSharedData final : public SourceSurfaceSharedData {
+ public:
+ MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(RecyclingSourceSurfaceSharedData,
+ override)
+
+ SurfaceType GetType() const override {
+ return SurfaceType::DATA_RECYCLING_SHARED;
+ }
+};
+
+static already_AddRefed<SourceSurfaceSharedData> AllocateBufferForImage(
+ const IntSize& size, SurfaceFormat format, bool aShouldRecycle = false) {
+ // Stride must be a multiple of four or cairo will complain.
+ int32_t stride = (size.width * BytesPerPixel(format) + 0x3) & ~0x3;
+
+ RefPtr<SourceSurfaceSharedData> newSurf;
+ if (aShouldRecycle) {
+ newSurf = new RecyclingSourceSurfaceSharedData();
+ } else {
+ newSurf = new SourceSurfaceSharedData();
+ }
+ if (!newSurf->Init(size, stride, format)) {
+ return nullptr;
+ }
+ return newSurf.forget();
+}
+
+static bool GreenSurface(SourceSurfaceSharedData* aSurface,
+ const IntSize& aSize, SurfaceFormat aFormat) {
+ int32_t stride = aSurface->Stride();
+ uint32_t* surfaceData = reinterpret_cast<uint32_t*>(aSurface->GetData());
+ uint32_t surfaceDataLength = (stride * aSize.height) / sizeof(uint32_t);
+
+ // Start by assuming that GG is in the second byte and
+ // AA is in the final byte -- the most common case.
+ uint32_t color = mozilla::NativeEndian::swapFromBigEndian(0x00FF00FF);
+
+ // We are only going to handle this type of test under
+ // certain circumstances.
+ MOZ_ASSERT(surfaceData);
+ MOZ_ASSERT(aFormat == SurfaceFormat::B8G8R8A8 ||
+ aFormat == SurfaceFormat::B8G8R8X8 ||
+ aFormat == SurfaceFormat::R8G8B8A8 ||
+ aFormat == SurfaceFormat::R8G8B8X8 ||
+ aFormat == SurfaceFormat::A8R8G8B8 ||
+ aFormat == SurfaceFormat::X8R8G8B8);
+ MOZ_ASSERT((stride * aSize.height) % sizeof(uint32_t));
+
+ if (aFormat == SurfaceFormat::A8R8G8B8 ||
+ aFormat == SurfaceFormat::X8R8G8B8) {
+ color = mozilla::NativeEndian::swapFromBigEndian(0xFF00FF00);
+ }
+
+ for (uint32_t i = 0; i < surfaceDataLength; i++) {
+ surfaceData[i] = color;
+ }
+
+ return true;
+}
+
+static bool ClearSurface(SourceSurfaceSharedData* aSurface,
+ const IntSize& aSize, SurfaceFormat aFormat) {
+ int32_t stride = aSurface->Stride();
+ uint8_t* data = aSurface->GetData();
+ MOZ_ASSERT(data);
+
+ if (aFormat == SurfaceFormat::OS_RGBX) {
+ // Skia doesn't support RGBX surfaces, so ensure the alpha value is set
+ // to opaque white. While it would be nice to only do this for Skia,
+ // imgFrame can run off main thread and past shutdown where
+ // we might not have gfxPlatform, so just memset every time instead.
+ memset(data, 0xFF, stride * aSize.height);
+ } else if (aSurface->OnHeap()) {
+ // We only need to memset it if the buffer was allocated on the heap.
+ // Otherwise, it's allocated via mmap and refers to a zeroed page and will
+ // be COW once it's written to.
+ memset(data, 0, stride * aSize.height);
+ }
+
+ return true;
+}
+
+imgFrame::imgFrame()
+ : mMonitor("imgFrame"),
+ mDecoded(0, 0, 0, 0),
+ mAborted(false),
+ mFinished(false),
+ mShouldRecycle(false),
+ mTimeout(FrameTimeout::FromRawMilliseconds(100)),
+ mDisposalMethod(DisposalMethod::NOT_SPECIFIED),
+ mBlendMethod(BlendMethod::OVER),
+ mFormat(SurfaceFormat::UNKNOWN),
+ mNonPremult(false) {}
+
+imgFrame::~imgFrame() {
+#ifdef DEBUG
+ MonitorAutoLock lock(mMonitor);
+ MOZ_ASSERT(mAborted || AreAllPixelsWritten());
+ MOZ_ASSERT(mAborted || mFinished);
+#endif
+}
+
+nsresult imgFrame::InitForDecoder(const nsIntSize& aImageSize,
+ SurfaceFormat aFormat, bool aNonPremult,
+ const Maybe<AnimationParams>& aAnimParams,
+ bool aShouldRecycle) {
+ // Assert for properties that should be verified by decoders,
+ // warn for properties related to bad content.
+ if (!SurfaceCache::IsLegalSize(aImageSize)) {
+ NS_WARNING("Should have legal image size");
+ MonitorAutoLock lock(mMonitor);
+ mAborted = true;
+ return NS_ERROR_FAILURE;
+ }
+
+ mImageSize = aImageSize;
+
+ // May be updated shortly after InitForDecoder by BlendAnimationFilter
+ // because it needs to take into consideration the previous frames to
+ // properly calculate. We start with the whole frame as dirty.
+ mDirtyRect = GetRect();
+
+ if (aAnimParams) {
+ mBlendRect = aAnimParams->mBlendRect;
+ mTimeout = aAnimParams->mTimeout;
+ mBlendMethod = aAnimParams->mBlendMethod;
+ mDisposalMethod = aAnimParams->mDisposalMethod;
+ } else {
+ mBlendRect = GetRect();
+ }
+
+ if (aShouldRecycle) {
+ // If we are recycling then we should always use BGRA for the underlying
+ // surface because if we use BGRX, the next frame composited into the
+ // surface could be BGRA and cause rendering problems.
+ MOZ_ASSERT(aAnimParams);
+ mFormat = SurfaceFormat::OS_RGBA;
+ } else {
+ mFormat = aFormat;
+ }
+
+ mNonPremult = aNonPremult;
+
+ MonitorAutoLock lock(mMonitor);
+ mShouldRecycle = aShouldRecycle;
+
+ MOZ_ASSERT(!mRawSurface, "Called imgFrame::InitForDecoder() twice?");
+
+ mRawSurface = AllocateBufferForImage(mImageSize, mFormat, mShouldRecycle);
+ if (!mRawSurface) {
+ mAborted = true;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ if (StaticPrefs::browser_measurement_render_anims_and_video_solid() &&
+ aAnimParams) {
+ mBlankRawSurface = AllocateBufferForImage(mImageSize, mFormat);
+ if (!mBlankRawSurface) {
+ mAborted = true;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ if (!ClearSurface(mRawSurface, mImageSize, mFormat)) {
+ NS_WARNING("Could not clear allocated buffer");
+ mAborted = true;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ if (mBlankRawSurface) {
+ if (!GreenSurface(mBlankRawSurface, mImageSize, mFormat)) {
+ NS_WARNING("Could not clear allocated blank buffer");
+ mAborted = true;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ return NS_OK;
+}
+
+nsresult imgFrame::InitForDecoderRecycle(const AnimationParams& aAnimParams) {
+ // We want to recycle this frame, but there is no guarantee that consumers are
+ // done with it in a timely manner. Let's ensure they are done with it first.
+ MonitorAutoLock lock(mMonitor);
+
+ MOZ_ASSERT(mRawSurface);
+
+ if (!mShouldRecycle) {
+ // This frame either was never marked as recyclable, or the flag was cleared
+ // for a caller which does not support recycling.
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ // Ensure we account for all internal references to the surface.
+ MozRefCountType internalRefs = 1;
+ if (mOptSurface == mRawSurface) {
+ ++internalRefs;
+ }
+
+ if (mRawSurface->refCount() > internalRefs) {
+ if (NS_IsMainThread()) {
+ // We should never be both decoding and recycling on the main thread. Sync
+ // decoding can only be used to produce the first set of frames. Those
+ // either never use recycling because advancing was blocked (main thread
+ // is busy) or we were auto-advancing (to seek to a frame) and the frames
+ // were never accessed (and thus cannot have recycle locks).
+ MOZ_ASSERT_UNREACHABLE("Recycling/decoding on the main thread?");
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ // We don't want to wait forever to reclaim the frame because we have no
+ // idea why it is still held. It is possibly due to OMTP. Since we are off
+ // the main thread, and we generally have frames already buffered for the
+ // animation, we can afford to wait a short period of time to hopefully
+ // complete the transaction and reclaim the buffer.
+ //
+ // We choose to wait for, at most, the refresh driver interval, so that we
+ // won't skip more than one frame. If the frame is still in use due to
+ // outstanding transactions, we are already skipping frames. If the frame
+ // is still in use for some other purpose, it won't be returned to the pool
+ // and its owner can hold onto it forever without additional impact here.
+ int32_t refreshInterval =
+ std::max(std::min(nsRefreshDriver::DefaultInterval(), 20), 4);
+ TimeDuration waitInterval =
+ TimeDuration::FromMilliseconds(refreshInterval >> 2);
+ TimeStamp timeout =
+ TimeStamp::Now() + TimeDuration::FromMilliseconds(refreshInterval);
+ while (true) {
+ mMonitor.Wait(waitInterval);
+ if (mRawSurface->refCount() <= internalRefs) {
+ break;
+ }
+
+ if (timeout <= TimeStamp::Now()) {
+ // We couldn't secure the frame for recycling. It will allocate a new
+ // frame instead.
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ }
+ }
+
+ mBlendRect = aAnimParams.mBlendRect;
+ mTimeout = aAnimParams.mTimeout;
+ mBlendMethod = aAnimParams.mBlendMethod;
+ mDisposalMethod = aAnimParams.mDisposalMethod;
+ mDirtyRect = GetRect();
+
+ return NS_OK;
+}
+
+nsresult imgFrame::InitWithDrawable(gfxDrawable* aDrawable,
+ const nsIntSize& aSize,
+ const SurfaceFormat aFormat,
+ SamplingFilter aSamplingFilter,
+ uint32_t aImageFlags,
+ gfx::BackendType aBackend) {
+ // Assert for properties that should be verified by decoders,
+ // warn for properties related to bad content.
+ if (!SurfaceCache::IsLegalSize(aSize)) {
+ NS_WARNING("Should have legal image size");
+ MonitorAutoLock lock(mMonitor);
+ mAborted = true;
+ return NS_ERROR_FAILURE;
+ }
+
+ mImageSize = aSize;
+ mFormat = aFormat;
+
+ RefPtr<DrawTarget> target;
+
+ bool canUseDataSurface = Factory::DoesBackendSupportDataDrawtarget(aBackend);
+ if (canUseDataSurface) {
+ MonitorAutoLock lock(mMonitor);
+ // It's safe to use data surfaces for content on this platform, so we can
+ // get away with using volatile buffers.
+ MOZ_ASSERT(!mRawSurface, "Called imgFrame::InitWithDrawable() twice?");
+
+ mRawSurface = AllocateBufferForImage(mImageSize, mFormat);
+ if (!mRawSurface) {
+ mAborted = true;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ if (!ClearSurface(mRawSurface, mImageSize, mFormat)) {
+ NS_WARNING("Could not clear allocated buffer");
+ mAborted = true;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ target = gfxPlatform::CreateDrawTargetForData(
+ mRawSurface->GetData(), mImageSize, mRawSurface->Stride(), mFormat);
+ } else {
+ // We can't use data surfaces for content, so we'll create an offscreen
+ // surface instead. This means if someone later calls RawAccessRef(), we
+ // may have to do an expensive readback, but we warned callers about that in
+ // the documentation for this method.
+#ifdef DEBUG
+ {
+ MonitorAutoLock lock(mMonitor);
+ MOZ_ASSERT(!mOptSurface, "Called imgFrame::InitWithDrawable() twice?");
+ }
+#endif
+
+ if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(aBackend)) {
+ target = gfxPlatform::GetPlatform()->CreateDrawTargetForBackend(
+ aBackend, mImageSize, mFormat);
+ } else {
+ target = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
+ mImageSize, mFormat);
+ }
+ }
+
+ if (!target || !target->IsValid()) {
+ MonitorAutoLock lock(mMonitor);
+ mAborted = true;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ // Draw using the drawable the caller provided.
+ gfxContext ctx(target);
+
+ gfxUtils::DrawPixelSnapped(&ctx, aDrawable, SizeDouble(mImageSize),
+ ImageRegion::Create(ThebesRect(GetRect())),
+ mFormat, aSamplingFilter, aImageFlags);
+
+ MonitorAutoLock lock(mMonitor);
+ if (canUseDataSurface && !mRawSurface) {
+ NS_WARNING("Failed to create SourceSurfaceSharedData");
+ mAborted = true;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ if (!canUseDataSurface) {
+ // We used an offscreen surface, which is an "optimized" surface from
+ // imgFrame's perspective.
+ mOptSurface = target->Snapshot();
+ } else {
+ FinalizeSurfaceInternal();
+ }
+
+ // If we reach this point, we should regard ourselves as complete.
+ mDecoded = GetRect();
+ mFinished = true;
+
+ MOZ_ASSERT(AreAllPixelsWritten());
+
+ return NS_OK;
+}
+
+DrawableFrameRef imgFrame::DrawableRef() { return DrawableFrameRef(this); }
+
+RawAccessFrameRef imgFrame::RawAccessRef() { return RawAccessFrameRef(this); }
+
+imgFrame::SurfaceWithFormat imgFrame::SurfaceForDrawing(
+ bool aDoPartialDecode, bool aDoTile, ImageRegion& aRegion,
+ SourceSurface* aSurface) {
+ MOZ_ASSERT(NS_IsMainThread());
+ mMonitor.AssertCurrentThreadOwns();
+
+ if (!aDoPartialDecode) {
+ return SurfaceWithFormat(new gfxSurfaceDrawable(aSurface, mImageSize),
+ mFormat);
+ }
+
+ gfxRect available =
+ gfxRect(mDecoded.X(), mDecoded.Y(), mDecoded.Width(), mDecoded.Height());
+
+ if (aDoTile) {
+ // Create a temporary surface.
+ // Give this surface an alpha channel because there are
+ // transparent pixels in the padding or undecoded area
+ RefPtr<DrawTarget> target =
+ gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
+ mImageSize, SurfaceFormat::OS_RGBA);
+ if (!target) {
+ return SurfaceWithFormat();
+ }
+
+ SurfacePattern pattern(aSurface, aRegion.GetExtendMode(),
+ Matrix::Translation(mDecoded.X(), mDecoded.Y()));
+ target->FillRect(ToRect(aRegion.Intersect(available).Rect()), pattern);
+
+ RefPtr<SourceSurface> newsurf = target->Snapshot();
+ return SurfaceWithFormat(new gfxSurfaceDrawable(newsurf, mImageSize),
+ target->GetFormat());
+ }
+
+ // Not tiling, and we have a surface, so we can account for
+ // a partial decode just by twiddling parameters.
+ aRegion = aRegion.Intersect(available);
+ IntSize availableSize(mDecoded.Width(), mDecoded.Height());
+
+ return SurfaceWithFormat(new gfxSurfaceDrawable(aSurface, availableSize),
+ mFormat);
+}
+
+bool imgFrame::Draw(gfxContext* aContext, const ImageRegion& aRegion,
+ SamplingFilter aSamplingFilter, uint32_t aImageFlags,
+ float aOpacity) {
+ AUTO_PROFILER_LABEL("imgFrame::Draw", GRAPHICS);
+
+ MOZ_ASSERT(NS_IsMainThread());
+ NS_ASSERTION(!aRegion.Rect().IsEmpty(), "Drawing empty region!");
+ NS_ASSERTION(!aRegion.IsRestricted() ||
+ !aRegion.Rect().Intersect(aRegion.Restriction()).IsEmpty(),
+ "We must be allowed to sample *some* source pixels!");
+
+ // Perform the draw and freeing of the surface outside the lock. We want to
+ // avoid contention with the decoder if we can. The surface may also attempt
+ // to relock the monitor if it is freed (e.g. RecyclingSourceSurface).
+ RefPtr<SourceSurface> surf;
+ SurfaceWithFormat surfaceResult;
+ ImageRegion region(aRegion);
+ gfxRect imageRect(0, 0, mImageSize.width, mImageSize.height);
+
+ {
+ MonitorAutoLock lock(mMonitor);
+
+ bool doPartialDecode = !AreAllPixelsWritten();
+
+ // Most draw targets will just use the surface only during DrawPixelSnapped
+ // but captures/recordings will retain a reference outside this stack
+ // context. While in theory a decoder thread could be trying to recycle this
+ // frame at this very moment, in practice the only way we can get here is if
+ // this frame is the current frame of the animation. Since we can only
+ // advance on the main thread, we know nothing else will try to use it.
+ DrawTarget* drawTarget = aContext->GetDrawTarget();
+ bool recording = drawTarget->GetBackendType() == BackendType::RECORDING;
+ RefPtr<SourceSurface> surf = GetSourceSurfaceInternal();
+ if (!surf) {
+ return false;
+ }
+
+ bool doTile = !imageRect.Contains(aRegion.Rect()) &&
+ !(aImageFlags & imgIContainer::FLAG_CLAMP);
+
+ surfaceResult = SurfaceForDrawing(doPartialDecode, doTile, region, surf);
+
+ // If we are recording, then we cannot recycle the surface. The blob
+ // rasterizer is not properly synchronized for recycling in the compositor
+ // process. The easiest thing to do is just mark the frames it consumes as
+ // non-recyclable.
+ if (recording && surfaceResult.IsValid()) {
+ mShouldRecycle = false;
+ }
+ }
+
+ if (surfaceResult.IsValid()) {
+ gfxUtils::DrawPixelSnapped(aContext, surfaceResult.mDrawable,
+ imageRect.Size(), region, surfaceResult.mFormat,
+ aSamplingFilter, aImageFlags, aOpacity);
+ }
+
+ return true;
+}
+
+nsresult imgFrame::ImageUpdated(const nsIntRect& aUpdateRect) {
+ MonitorAutoLock lock(mMonitor);
+ return ImageUpdatedInternal(aUpdateRect);
+}
+
+nsresult imgFrame::ImageUpdatedInternal(const nsIntRect& aUpdateRect) {
+ mMonitor.AssertCurrentThreadOwns();
+
+ // Clamp to the frame rect to ensure that decoder bugs don't result in a
+ // decoded rect that extends outside the bounds of the frame rect.
+ IntRect updateRect = aUpdateRect.Intersect(GetRect());
+ if (updateRect.IsEmpty()) {
+ return NS_OK;
+ }
+
+ mDecoded.UnionRect(mDecoded, updateRect);
+
+ // Update our invalidation counters for any consumers watching for changes
+ // in the surface.
+ if (mRawSurface) {
+ mRawSurface->Invalidate(updateRect);
+ }
+ return NS_OK;
+}
+
+void imgFrame::Finish(Opacity aFrameOpacity /* = Opacity::SOME_TRANSPARENCY */,
+ bool aFinalize /* = true */,
+ bool aOrientationSwapsWidthAndHeight /* = false */) {
+ MonitorAutoLock lock(mMonitor);
+
+ IntRect frameRect(GetRect());
+ if (!mDecoded.IsEqualEdges(frameRect)) {
+ // The decoder should have produced rows starting from either the bottom or
+ // the top of the image. We need to calculate the region for which we have
+ // not yet invalidated. And if the orientation swaps width and height then
+ // its from the left or right.
+ IntRect delta(0, 0, frameRect.width, 0);
+ if (!aOrientationSwapsWidthAndHeight) {
+ delta.width = frameRect.width;
+ if (mDecoded.y == 0) {
+ delta.y = mDecoded.height;
+ delta.height = frameRect.height - mDecoded.height;
+ } else if (mDecoded.y + mDecoded.height == frameRect.height) {
+ delta.height = frameRect.height - mDecoded.y;
+ } else {
+ MOZ_ASSERT_UNREACHABLE("Decoder only updated middle of image!");
+ delta = frameRect;
+ }
+ } else {
+ delta.height = frameRect.height;
+ if (mDecoded.x == 0) {
+ delta.x = mDecoded.width;
+ delta.width = frameRect.width - mDecoded.width;
+ } else if (mDecoded.x + mDecoded.width == frameRect.width) {
+ delta.width = frameRect.width - mDecoded.x;
+ } else {
+ MOZ_ASSERT_UNREACHABLE("Decoder only updated middle of image!");
+ delta = frameRect;
+ }
+ }
+
+ ImageUpdatedInternal(delta);
+ }
+
+ MOZ_ASSERT(mDecoded.IsEqualEdges(frameRect));
+
+ if (aFinalize) {
+ FinalizeSurfaceInternal();
+ }
+
+ mFinished = true;
+
+ // The image is now complete, wake up anyone who's waiting.
+ mMonitor.NotifyAll();
+}
+
+uint32_t imgFrame::GetImageBytesPerRow() const {
+ mMonitor.AssertCurrentThreadOwns();
+
+ if (mRawSurface) {
+ return mImageSize.width * BytesPerPixel(mFormat);
+ }
+
+ return 0;
+}
+
+uint32_t imgFrame::GetImageDataLength() const {
+ return GetImageBytesPerRow() * mImageSize.height;
+}
+
+void imgFrame::GetImageData(uint8_t** aData, uint32_t* aLength) const {
+ MonitorAutoLock lock(mMonitor);
+ GetImageDataInternal(aData, aLength);
+}
+
+void imgFrame::GetImageDataInternal(uint8_t** aData, uint32_t* aLength) const {
+ mMonitor.AssertCurrentThreadOwns();
+ MOZ_ASSERT(mRawSurface);
+
+ if (mRawSurface) {
+ // TODO: This is okay for now because we only realloc shared surfaces on
+ // the main thread after decoding has finished, but if animations want to
+ // read frame data off the main thread, we will need to reconsider this.
+ *aData = mRawSurface->GetData();
+ MOZ_ASSERT(*aData,
+ "mRawSurface is non-null, but GetData is null in GetImageData");
+ } else {
+ *aData = nullptr;
+ }
+
+ *aLength = GetImageDataLength();
+}
+
+uint8_t* imgFrame::GetImageData() const {
+ uint8_t* data;
+ uint32_t length;
+ GetImageData(&data, &length);
+ return data;
+}
+
+void imgFrame::FinalizeSurface() {
+ MonitorAutoLock lock(mMonitor);
+ FinalizeSurfaceInternal();
+}
+
+void imgFrame::FinalizeSurfaceInternal() {
+ mMonitor.AssertCurrentThreadOwns();
+
+ // Not all images will have mRawSurface to finalize (i.e. paletted images).
+ if (mShouldRecycle || !mRawSurface ||
+ mRawSurface->GetType() != SurfaceType::DATA_SHARED) {
+ return;
+ }
+
+ auto* sharedSurf = static_cast<SourceSurfaceSharedData*>(mRawSurface.get());
+ sharedSurf->Finalize();
+}
+
+already_AddRefed<SourceSurface> imgFrame::GetSourceSurface() {
+ MonitorAutoLock lock(mMonitor);
+ return GetSourceSurfaceInternal();
+}
+
+already_AddRefed<SourceSurface> imgFrame::GetSourceSurfaceInternal() {
+ mMonitor.AssertCurrentThreadOwns();
+
+ if (mOptSurface) {
+ if (mOptSurface->IsValid()) {
+ RefPtr<SourceSurface> surf(mOptSurface);
+ return surf.forget();
+ }
+ mOptSurface = nullptr;
+ }
+
+ if (mBlankRawSurface) {
+ // We are going to return the blank surface because of the flags.
+ // We are including comments here that are copied from below
+ // just so that we are on the same page!
+ RefPtr<SourceSurface> surf(mBlankRawSurface);
+ return surf.forget();
+ }
+
+ RefPtr<SourceSurface> surf(mRawSurface);
+ return surf.forget();
+}
+
+void imgFrame::Abort() {
+ MonitorAutoLock lock(mMonitor);
+
+ mAborted = true;
+
+ // Wake up anyone who's waiting.
+ mMonitor.NotifyAll();
+}
+
+bool imgFrame::IsAborted() const {
+ MonitorAutoLock lock(mMonitor);
+ return mAborted;
+}
+
+bool imgFrame::IsFinished() const {
+ MonitorAutoLock lock(mMonitor);
+ return mFinished;
+}
+
+void imgFrame::WaitUntilFinished() const {
+ MonitorAutoLock lock(mMonitor);
+
+ while (true) {
+ // Return if we're aborted or complete.
+ if (mAborted || mFinished) {
+ return;
+ }
+
+ // Not complete yet, so we'll have to wait.
+ mMonitor.Wait();
+ }
+}
+
+bool imgFrame::AreAllPixelsWritten() const {
+ mMonitor.AssertCurrentThreadOwns();
+ return mDecoded.IsEqualInterior(GetRect());
+}
+
+void imgFrame::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
+ const AddSizeOfCb& aCallback) const {
+ MonitorAutoLock lock(mMonitor);
+
+ AddSizeOfCbData metadata;
+ metadata.mFinished = mFinished;
+
+ if (mOptSurface) {
+ metadata.mHeapBytes += aMallocSizeOf(mOptSurface);
+
+ SourceSurface::SizeOfInfo info;
+ mOptSurface->SizeOfExcludingThis(aMallocSizeOf, info);
+ metadata.Accumulate(info);
+ }
+ if (mRawSurface) {
+ metadata.mHeapBytes += aMallocSizeOf(mRawSurface);
+
+ SourceSurface::SizeOfInfo info;
+ mRawSurface->SizeOfExcludingThis(aMallocSizeOf, info);
+ metadata.Accumulate(info);
+ }
+
+ aCallback(metadata);
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/imgFrame.h b/image/imgFrame.h
new file mode 100644
index 0000000000..c0049c36ca
--- /dev/null
+++ b/image/imgFrame.h
@@ -0,0 +1,422 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_imgFrame_h
+#define mozilla_image_imgFrame_h
+
+#include <functional>
+#include <utility>
+
+#include "AnimationParams.h"
+#include "MainThreadUtils.h"
+#include "gfxDrawable.h"
+#include "mozilla/layers/SourceSurfaceSharedData.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/Monitor.h"
+#include "nsRect.h"
+
+namespace mozilla {
+namespace image {
+
+class ImageRegion;
+class DrawableFrameRef;
+class RawAccessFrameRef;
+
+enum class Opacity : uint8_t { FULLY_OPAQUE, SOME_TRANSPARENCY };
+
+class imgFrame {
+ typedef gfx::SourceSurfaceSharedData SourceSurfaceSharedData;
+ typedef gfx::DrawTarget DrawTarget;
+ typedef gfx::SamplingFilter SamplingFilter;
+ typedef gfx::IntPoint IntPoint;
+ typedef gfx::IntRect IntRect;
+ typedef gfx::IntSize IntSize;
+ typedef gfx::SourceSurface SourceSurface;
+ typedef gfx::SurfaceFormat SurfaceFormat;
+
+ public:
+ MOZ_DECLARE_REFCOUNTED_TYPENAME(imgFrame)
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(imgFrame)
+
+ imgFrame();
+
+ /**
+ * Initialize this imgFrame with an empty surface and prepare it for being
+ * written to by a decoder.
+ *
+ * This is appropriate for use with decoded images, but it should not be used
+ * when drawing content into an imgFrame, as it may use a different graphics
+ * backend than normal content drawing.
+ */
+ nsresult InitForDecoder(const nsIntSize& aImageSize, SurfaceFormat aFormat,
+ bool aNonPremult,
+ const Maybe<AnimationParams>& aAnimParams,
+ bool aShouldRecycle);
+
+ /**
+ * Reinitialize this imgFrame with the new parameters, but otherwise retain
+ * the underlying buffer.
+ *
+ * This is appropriate for use with animated images, where the decoder was
+ * given an IDecoderFrameRecycler object which may yield a recycled imgFrame
+ * that was discarded to save memory.
+ */
+ nsresult InitForDecoderRecycle(const AnimationParams& aAnimParams);
+
+ /**
+ * Initialize this imgFrame with a new surface and draw the provided
+ * gfxDrawable into it.
+ *
+ * This is appropriate to use when drawing content into an imgFrame, as it
+ * uses the same graphics backend as normal content drawing. The downside is
+ * that the underlying surface may not be stored in a volatile buffer on all
+ * platforms, and raw access to the surface (using RawAccessRef()) may be much
+ * more expensive than in the InitForDecoder() case.
+ *
+ * aBackend specifies the DrawTarget backend type this imgFrame is supposed
+ * to be drawn to.
+ */
+ nsresult InitWithDrawable(gfxDrawable* aDrawable, const nsIntSize& aSize,
+ const SurfaceFormat aFormat,
+ SamplingFilter aSamplingFilter,
+ uint32_t aImageFlags, gfx::BackendType aBackend);
+
+ DrawableFrameRef DrawableRef();
+
+ /**
+ * Create a RawAccessFrameRef for the frame.
+ */
+ RawAccessFrameRef RawAccessRef();
+
+ bool Draw(gfxContext* aContext, const ImageRegion& aRegion,
+ SamplingFilter aSamplingFilter, uint32_t aImageFlags,
+ float aOpacity);
+
+ nsresult ImageUpdated(const nsIntRect& aUpdateRect);
+
+ /**
+ * Mark this imgFrame as completely decoded, and set final options.
+ *
+ * You must always call either Finish() or Abort() before releasing the last
+ * RawAccessFrameRef pointing to an imgFrame.
+ *
+ * @param aFrameOpacity Whether this imgFrame is opaque.
+ * @param aFinalize Finalize the underlying surface (e.g. so that it
+ * may be marked as read only if possible).
+ */
+ void Finish(Opacity aFrameOpacity = Opacity::SOME_TRANSPARENCY,
+ bool aFinalize = true,
+ bool aOrientationSwapsWidthAndHeight = false);
+
+ /**
+ * Mark this imgFrame as aborted. This informs the imgFrame that if it isn't
+ * completely decoded now, it never will be.
+ *
+ * You must always call either Finish() or Abort() before releasing the last
+ * RawAccessFrameRef pointing to an imgFrame.
+ */
+ void Abort();
+
+ /**
+ * Returns true if this imgFrame has been aborted.
+ */
+ bool IsAborted() const;
+
+ /**
+ * Returns true if this imgFrame is completely decoded.
+ */
+ bool IsFinished() const;
+
+ /**
+ * Blocks until this imgFrame is either completely decoded, or is marked as
+ * aborted.
+ *
+ * Note that calling this on the main thread _blocks the main thread_. Be very
+ * careful in your use of this method to avoid excessive main thread jank or
+ * deadlock.
+ */
+ void WaitUntilFinished() const;
+
+ /**
+ * Returns the number of bytes per pixel this imgFrame requires.
+ */
+ uint32_t GetBytesPerPixel() const { return 4; }
+
+ const IntSize& GetSize() const { return mImageSize; }
+ IntRect GetRect() const { return IntRect(IntPoint(0, 0), mImageSize); }
+ const IntRect& GetBlendRect() const { return mBlendRect; }
+ IntRect GetBoundedBlendRect() const {
+ return mBlendRect.Intersect(GetRect());
+ }
+ nsIntRect GetDecodedRect() const {
+ MonitorAutoLock lock(mMonitor);
+ return mDecoded;
+ }
+ FrameTimeout GetTimeout() const { return mTimeout; }
+ BlendMethod GetBlendMethod() const { return mBlendMethod; }
+ DisposalMethod GetDisposalMethod() const { return mDisposalMethod; }
+ bool FormatHasAlpha() const { return mFormat == SurfaceFormat::OS_RGBA; }
+ void GetImageData(uint8_t** aData, uint32_t* length) const;
+ uint8_t* GetImageData() const;
+
+ const IntRect& GetDirtyRect() const { return mDirtyRect; }
+ void SetDirtyRect(const IntRect& aDirtyRect) { mDirtyRect = aDirtyRect; }
+
+ void FinalizeSurface();
+ already_AddRefed<SourceSurface> GetSourceSurface();
+
+ struct AddSizeOfCbData : public SourceSurface::SizeOfInfo {
+ AddSizeOfCbData()
+ : SourceSurface::SizeOfInfo(), mIndex(0), mFinished(false) {}
+
+ size_t mIndex;
+ bool mFinished;
+ };
+
+ typedef std::function<void(AddSizeOfCbData& aMetadata)> AddSizeOfCb;
+
+ void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
+ const AddSizeOfCb& aCallback) const;
+
+ private: // methods
+ ~imgFrame();
+
+ bool AreAllPixelsWritten() const MOZ_REQUIRES(mMonitor);
+ nsresult ImageUpdatedInternal(const nsIntRect& aUpdateRect);
+ void GetImageDataInternal(uint8_t** aData, uint32_t* length) const;
+ uint32_t GetImageBytesPerRow() const;
+ uint32_t GetImageDataLength() const;
+ void FinalizeSurfaceInternal();
+ already_AddRefed<SourceSurface> GetSourceSurfaceInternal();
+
+ struct SurfaceWithFormat {
+ RefPtr<gfxDrawable> mDrawable;
+ SurfaceFormat mFormat;
+ SurfaceWithFormat() : mFormat(SurfaceFormat::UNKNOWN) {}
+ SurfaceWithFormat(gfxDrawable* aDrawable, SurfaceFormat aFormat)
+ : mDrawable(aDrawable), mFormat(aFormat) {}
+ SurfaceWithFormat(SurfaceWithFormat&& aOther)
+ : mDrawable(std::move(aOther.mDrawable)), mFormat(aOther.mFormat) {}
+ SurfaceWithFormat& operator=(SurfaceWithFormat&& aOther) {
+ mDrawable = std::move(aOther.mDrawable);
+ mFormat = aOther.mFormat;
+ return *this;
+ }
+ SurfaceWithFormat& operator=(const SurfaceWithFormat& aOther) = delete;
+ SurfaceWithFormat(const SurfaceWithFormat& aOther) = delete;
+ bool IsValid() { return !!mDrawable; }
+ };
+
+ SurfaceWithFormat SurfaceForDrawing(bool aDoPartialDecode, bool aDoTile,
+ ImageRegion& aRegion,
+ SourceSurface* aSurface);
+
+ private: // data
+ friend class DrawableFrameRef;
+ friend class RawAccessFrameRef;
+ friend class UnlockImageDataRunnable;
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Thread-safe mutable data, protected by mMonitor.
+ //////////////////////////////////////////////////////////////////////////////
+
+ mutable Monitor mMonitor;
+
+ /**
+ * Used for rasterized images, this contains the raw pixel data.
+ */
+ RefPtr<SourceSurfaceSharedData> mRawSurface MOZ_GUARDED_BY(mMonitor);
+ RefPtr<SourceSurfaceSharedData> mBlankRawSurface MOZ_GUARDED_BY(mMonitor);
+
+ /**
+ * Used for vector images that were not rasterized directly. This might be a
+ * blob recording or native surface.
+ */
+ RefPtr<SourceSurface> mOptSurface MOZ_GUARDED_BY(mMonitor);
+
+ nsIntRect mDecoded MOZ_GUARDED_BY(mMonitor);
+
+ bool mAborted MOZ_GUARDED_BY(mMonitor);
+ bool mFinished MOZ_GUARDED_BY(mMonitor);
+ bool mShouldRecycle MOZ_GUARDED_BY(mMonitor);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Effectively const data, only mutated in the Init methods.
+ //////////////////////////////////////////////////////////////////////////////
+
+ //! The size of the buffer we are decoding to.
+ IntSize mImageSize;
+
+ //! The contents for the frame, as represented in the encoded image. This may
+ //! differ from mImageSize because it may be a partial frame. For the first
+ //! frame, this means we need to shift the data in place, and for animated
+ //! frames, it likely need to combine with a previous frame to get the full
+ //! contents.
+ IntRect mBlendRect;
+
+ //! This is the region that has changed between this frame and the previous
+ //! frame of an animation. For the first frame, this will be the same as
+ //! mFrameRect.
+ IntRect mDirtyRect;
+
+ //! The timeout for this frame.
+ FrameTimeout mTimeout;
+
+ DisposalMethod mDisposalMethod;
+ BlendMethod mBlendMethod;
+ SurfaceFormat mFormat;
+
+ bool mNonPremult;
+};
+
+/**
+ * A reference to an imgFrame that holds the imgFrame's surface in memory,
+ * allowing drawing. If you have a DrawableFrameRef |ref| and |if (ref)| returns
+ * true, then calls to Draw() and GetSourceSurface() are guaranteed to succeed.
+ */
+class DrawableFrameRef final {
+ typedef gfx::DataSourceSurface DataSourceSurface;
+
+ public:
+ DrawableFrameRef() {}
+
+ explicit DrawableFrameRef(imgFrame* aFrame) : mFrame(aFrame) {
+ MOZ_ASSERT(aFrame);
+ MonitorAutoLock lock(aFrame->mMonitor);
+
+ if (aFrame->mRawSurface) {
+ mRef.emplace(aFrame->mRawSurface, DataSourceSurface::READ);
+ if (!mRef->IsMapped()) {
+ mFrame = nullptr;
+ mRef.reset();
+ }
+ } else if (!aFrame->mOptSurface || !aFrame->mOptSurface->IsValid()) {
+ // The optimized surface has become invalid, so we need to redecode.
+ // For example, on Windows, there may have been a device reset, and
+ // all D2D surfaces now need to be recreated.
+ mFrame = nullptr;
+ }
+ }
+
+ DrawableFrameRef(DrawableFrameRef&& aOther)
+ : mFrame(std::move(aOther.mFrame)), mRef(std::move(aOther.mRef)) {}
+
+ DrawableFrameRef& operator=(DrawableFrameRef&& aOther) {
+ MOZ_ASSERT(this != &aOther, "Self-moves are prohibited");
+ mFrame = std::move(aOther.mFrame);
+ mRef = std::move(aOther.mRef);
+ return *this;
+ }
+
+ explicit operator bool() const { return bool(mFrame); }
+
+ imgFrame* operator->() {
+ MOZ_ASSERT(mFrame);
+ return mFrame;
+ }
+
+ const imgFrame* operator->() const {
+ MOZ_ASSERT(mFrame);
+ return mFrame;
+ }
+
+ imgFrame* get() { return mFrame; }
+ const imgFrame* get() const { return mFrame; }
+
+ void reset() {
+ mFrame = nullptr;
+ mRef.reset();
+ }
+
+ private:
+ DrawableFrameRef(const DrawableFrameRef& aOther) = delete;
+ DrawableFrameRef& operator=(const DrawableFrameRef& aOther) = delete;
+
+ RefPtr<imgFrame> mFrame;
+ Maybe<DataSourceSurface::ScopedMap> mRef;
+};
+
+/**
+ * A reference to an imgFrame that holds the imgFrame's surface in memory in a
+ * format appropriate for access as raw data. If you have a RawAccessFrameRef
+ * |ref| and |if (ref)| is true, then calls to GetImageData() is guaranteed to
+ * succeed. This guarantee is stronger than DrawableFrameRef, so everything that
+ * a valid DrawableFrameRef guarantees is also guaranteed by a valid
+ * RawAccessFrameRef.
+ *
+ * This may be considerably more expensive than is necessary just for drawing,
+ * so only use this when you need to read or write the raw underlying image data
+ * that the imgFrame holds.
+ *
+ * Once all an imgFrame's RawAccessFrameRefs go out of scope, new
+ * RawAccessFrameRefs cannot be created.
+ */
+class RawAccessFrameRef final {
+ public:
+ RawAccessFrameRef() : mData(nullptr) {}
+
+ explicit RawAccessFrameRef(imgFrame* aFrame)
+ : mFrame(aFrame), mData(nullptr) {
+ MOZ_ASSERT(mFrame, "Need a frame");
+
+ mData = mFrame->GetImageData();
+ if (!mData) {
+ mFrame = nullptr;
+ }
+ }
+
+ RawAccessFrameRef(RawAccessFrameRef&& aOther)
+ : mFrame(std::move(aOther.mFrame)), mData(aOther.mData) {
+ aOther.mData = nullptr;
+ }
+
+ ~RawAccessFrameRef() {}
+
+ RawAccessFrameRef& operator=(RawAccessFrameRef&& aOther) {
+ MOZ_ASSERT(this != &aOther, "Self-moves are prohibited");
+
+ mFrame = std::move(aOther.mFrame);
+ mData = aOther.mData;
+ aOther.mData = nullptr;
+
+ return *this;
+ }
+
+ explicit operator bool() const { return bool(mFrame); }
+
+ imgFrame* operator->() {
+ MOZ_ASSERT(mFrame);
+ return mFrame.get();
+ }
+
+ const imgFrame* operator->() const {
+ MOZ_ASSERT(mFrame);
+ return mFrame;
+ }
+
+ imgFrame* get() { return mFrame; }
+ const imgFrame* get() const { return mFrame; }
+
+ void reset() {
+ mFrame = nullptr;
+ mData = nullptr;
+ }
+
+ uint8_t* Data() const { return mData; }
+
+ private:
+ RawAccessFrameRef(const RawAccessFrameRef& aOther) = delete;
+ RawAccessFrameRef& operator=(const RawAccessFrameRef& aOther) = delete;
+
+ RefPtr<imgFrame> mFrame;
+ uint8_t* mData;
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_imgFrame_h
diff --git a/image/imgICache.idl b/image/imgICache.idl
new file mode 100644
index 0000000000..2368dfc961
--- /dev/null
+++ b/image/imgICache.idl
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface imgIRequest;
+interface nsIPrincipal;
+interface nsIProperties;
+interface nsIURI;
+
+webidl Document;
+
+%{ C++
+namespace mozilla {
+class OriginAttributes;
+} // mozilla namespace
+%}
+
+[ptr] native OriginAttributesPtr(mozilla::OriginAttributes);
+
+/**
+ * imgICache interface
+ *
+ * @author Stuart Parmenter <pavlov@netscape.com>
+ * @version 0.1
+ * @see imagelib2
+ */
+[scriptable, builtinclass, uuid(bfdf23ff-378e-402e-8a6c-840f0c82b6c3)]
+interface imgICache : nsISupports
+{
+ /**
+ * Evict images from the cache.
+ *
+ * @param chrome If TRUE, evict only chrome images.
+ * If FALSE, evict everything except chrome images.
+ */
+ void clearCache(in boolean chrome);
+
+ /**
+ * Evict images from the cache.
+ *
+ * @param uri The URI to remove.
+ * @param doc The document to remove the cache entry for.
+ * @throws NS_ERROR_NOT_AVAILABLE if \a uri was unable to be removed from
+ * the cache.
+ */
+ [noscript] void removeEntry(in nsIURI uri, [optional] in Document doc);
+
+ /**
+ * Evict images from the cache with the same origin and the same
+ * originAttributes of the passed principal, across all processes. May only be
+ * called from the parent process.
+ *
+ * @param aPrincipal The principal to clear cache entries for. The principals
+ * origin attributes are used to determine whether the private or normal
+ * browsing cache is cleared.
+ * @throws NS_ERROR_NOT_AVAILABLE if not called in the parent process.
+ */
+ void removeEntriesFromPrincipalInAllProcesses(in nsIPrincipal aPrincipal);
+
+ /**
+ * Evict images from the non-chrome cache which match the the given base
+ * domain. Matching cache entries will be cleared across all origin attributes
+ * and all processes.
+ *
+ * @param aBaseDomain base domain to delete cache entries for.
+ * @throws NS_ERROR_NOT_AVAILABLE if not called in the parent process.
+ */
+ void removeEntriesFromBaseDomainInAllProcesses(in ACString aBaseDomain);
+
+ /**
+ * Find Properties
+ * Used to get properties such as 'type' and 'content-disposition'
+ * 'type' is a nsISupportsCString containing the images' mime type such as
+ * 'image/png'
+ * 'content-disposition' will be a nsISupportsCString containing the header
+ * If you call this before any data has been loaded from a URI, it will
+ * succeed, but come back empty.
+ *
+ * Hopefully this will be removed with bug 805119
+ *
+ * @param uri The URI to look up.
+ * @param doc Optional pointer to the document that the cache entry belongs to.
+ * @returns NULL if the URL was not found in the cache
+ */
+ [must_use]
+ nsIProperties findEntryProperties(in nsIURI uri,
+ [optional] in Document doc);
+
+ /**
+ * Make this cache instance respect private browsing notifications. This
+ * entails clearing the chrome and content caches whenever the
+ * last-pb-context-exited notification is observed.
+ */
+ void respectPrivacyNotifications();
+
+ /**
+ * Clear the image cache for a document. Controlled documents are responsible
+ * for doing this manually when they get destroyed.
+ */
+ [noscript, notxpcom]
+ void clearCacheForControlledDocument(in Document doc);
+};
diff --git a/image/imgIContainer.idl b/image/imgIContainer.idl
new file mode 100644
index 0000000000..abbc827878
--- /dev/null
+++ b/image/imgIContainer.idl
@@ -0,0 +1,692 @@
+/** -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+webidl Document;
+
+%{C++
+#include "ImgDrawResult.h"
+#include "gfxPoint.h"
+#include "mozilla/gfx/Types.h"
+#include "mozilla/AspectRatio.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/RefPtr.h"
+#include "nsRect.h"
+#include "nsSize.h"
+#include "nsTArray.h"
+#include "limits.h"
+
+class gfxContext;
+
+namespace mozilla {
+struct AspectRatio;
+
+namespace gfx {
+class SourceSurface;
+}
+
+class WindowRenderer;
+namespace layers {
+class ImageContainer;
+}
+}
+
+class nsIFrame;
+
+namespace mozilla {
+class TimeStamp;
+class SVGImageContext;
+struct MediaFeatureChange;
+}
+
+namespace mozilla {
+namespace image {
+
+class ImageRegion;
+class ImageIntRegion;
+class WebRenderImageProvider;
+struct Orientation;
+struct Resolution;
+
+}
+}
+
+%}
+
+native MaybeAspectRatio(mozilla::Maybe<mozilla::AspectRatio>);
+native ImgDrawResult(mozilla::image::ImgDrawResult);
+[ptr] native gfxContext(gfxContext);
+[ref] native gfxMatrix(gfxMatrix);
+[ref] native gfxRect(gfxRect);
+[ref] native gfxSize(gfxSize);
+native SamplingFilter(mozilla::gfx::SamplingFilter);
+[ref] native nsIntRect(nsIntRect);
+native nsIntRectByVal(nsIntRect);
+[ref] native nsIntSize(nsIntSize);
+native nsSize(nsSize);
+[ptr] native nsIFrame(nsIFrame);
+native TempRefImageContainer(already_AddRefed<mozilla::layers::ImageContainer>);
+[ptr] native ImageContainer(mozilla::layers::ImageContainer);
+[ptr] native WebRenderImageProvider(mozilla::image::WebRenderImageProvider);
+[ref] native ImageRegion(mozilla::image::ImageRegion);
+[ptr] native WindowRenderer(mozilla::WindowRenderer);
+native Orientation(mozilla::image::Orientation);
+native ImageResolution(mozilla::image::Resolution);
+[ref] native TimeStamp(mozilla::TimeStamp);
+[ref] native SVGImageContext(mozilla::SVGImageContext);
+[ref] native MaybeImageIntRegion(mozilla::Maybe<mozilla::image::ImageIntRegion>);
+native TempRefSourceSurface(already_AddRefed<mozilla::gfx::SourceSurface>);
+native TempRefImgIContainer(already_AddRefed<imgIContainer>);
+native nsIntSizeByVal(nsIntSize);
+[ref] native MediaFeatureChange(mozilla::MediaFeatureChange);
+
+
+/**
+ * imgIContainer is the interface that represents an image. It allows
+ * access to frames as Thebes surfaces. It also allows drawing of images
+ * onto Thebes contexts.
+ *
+ * Internally, imgIContainer also manages animation of images.
+ */
+[scriptable, builtinclass, uuid(a8dbee24-ff86-4755-b40e-51175caf31af)]
+interface imgIContainer : nsISupports
+{
+ /**
+ * The width of the container rectangle. In the case of any error,
+ * zero is returned, and an exception will be thrown.
+ */
+ readonly attribute int32_t width;
+
+ /**
+ * The height of the container rectangle. In the case of any error,
+ * zero is returned, and an exception will be thrown.
+ */
+ readonly attribute int32_t height;
+
+ /**
+ * The intrinsic size of this image in appunits. If the image has no intrinsic
+ * size in a dimension, -1 will be returned for that dimension. In the case of
+ * any error, an exception will be thrown.
+ */
+ [noscript] readonly attribute nsSize intrinsicSize;
+
+ /**
+ * The (dimensionless) intrinsic ratio of this image. In the case of any
+ * error, Nothing() will be returned.
+ */
+ [notxpcom, nostdcall] readonly attribute MaybeAspectRatio intrinsicRatio;
+
+ /**
+ * The x coordinate of the image's hotspot, or 0 if there is no hotspot.
+ */
+ readonly attribute int32_t hotspotX;
+
+ /**
+ * The y coordinate of the image's hotspot, or 0 if there is no hotspot.
+ */
+ readonly attribute int32_t hotspotY;
+
+ /**
+ * Given a size at which this image will be displayed, and the drawing
+ * parameters affecting how it will be drawn, returns the image size which
+ * should be used to draw to produce the highest quality result. This is the
+ * appropriate size, for example, to use as an input to the pixel snapping
+ * algorithm.
+ *
+ * For best results the size returned by this method should not be cached. It
+ * can change over time due to changes in the internal state of the image.
+ *
+ * @param aDest The size of the destination rect into which this image will be
+ * drawn, in device pixels.
+ * @param aWhichFrame Frame specifier of the FRAME_* variety.
+ * @param aSamplingFilter The filter to be used if we're scaling the image.
+ * @param aFlags Flags of the FLAG_* variety
+ */
+ [notxpcom, nostdcall] nsIntSizeByVal
+ optimalImageSizeForDest([const] in gfxSize aDest, in uint32_t aWhichFrame,
+ in SamplingFilter aSamplingFilter, in uint32_t aFlags);
+
+ /**
+ * Enumerated values for the 'type' attribute (below).
+ */
+ const unsigned short TYPE_RASTER = 0;
+ const unsigned short TYPE_VECTOR = 1;
+ const unsigned short TYPE_REQUEST = 2;
+
+ /**
+ * The type of this image (one of the TYPE_* values above).
+ */
+ [infallible] readonly attribute unsigned short type;
+
+ /**
+ * Whether this image is animated. You can only be guaranteed that querying
+ * this will not throw if STATUS_DECODE_COMPLETE is set on the imgIRequest.
+ *
+ * @throws NS_ERROR_NOT_AVAILABLE if the animated state cannot be determined.
+ */
+ readonly attribute boolean animated;
+
+ /**
+ * Provider ID for image providers created by this image.
+ */
+ [infallible] readonly attribute unsigned long providerId;
+
+ /**
+ * Flags for imgIContainer operations.
+ *
+ * Meanings:
+ *
+ * FLAG_NONE: Lack of flags.
+ *
+ * FLAG_SYNC_DECODE: Forces synchronous/non-progressive decode of all
+ * available data before the call returns.
+ *
+ * FLAG_SYNC_DECODE_IF_FAST: Like FLAG_SYNC_DECODE, but requests a sync decode
+ * be performed only if ImageLib estimates it can be completed very quickly.
+ *
+ * FLAG_ASYNC_NOTIFY: Send notifications asynchronously, even if we decode
+ * synchronously because of FLAG_SYNC_DECODE or FLAG_SYNC_DECODE_IF_FAST.
+ *
+ * FLAG_DECODE_NO_PREMULTIPLY_ALPHA: Do not premultiply alpha if
+ * it's not already premultiplied in the image data.
+ *
+ * FLAG_DECODE_NO_COLORSPACE_CONVERSION: Do not do any colorspace conversion;
+ * ignore any embedded profiles, and don't convert to any particular
+ * destination space.
+ *
+ * FLAG_CLAMP: Extend the image to the fill area by clamping image sample
+ * coordinates instead of by tiling. This only affects 'draw'.
+ *
+ * FLAG_HIGH_QUALITY_SCALING: A hint as to whether this image should be
+ * scaled using the high quality scaler. Do not set this if not drawing to
+ * a window or not listening to invalidations. Passing this flag will do two
+ * things: 1) request a decode of the image at the size asked for by the
+ * caller if one isn't already started or complete, and 2) allows a decoded
+ * frame of any size (it could be neither the requested size, nor the
+ * intrinsic size) to be substituted.
+ *
+ * FLAG_BYPASS_SURFACE_CACHE: Forces drawing to happen rather than taking
+ * cached rendering from the surface cache. This is used when we are printing,
+ * for example, where we want the vector commands from VectorImages to end up
+ * in the PDF output rather than a cached rendering at screen resolution.
+ *
+ * FLAG_FORCE_PRESERVEASPECTRATIO_NONE: Force scaling this image
+ * non-uniformly if necessary. This flag is for vector image only. A raster
+ * image should ignore this flag. While drawing a vector image with this
+ * flag, do not force uniform scaling even if its root <svg> node has a
+ * preserveAspectRatio attribute that would otherwise require uniform
+ * scaling , such as xMinYMin/ xMidYMin. Always scale the graphic content of
+ * the given image non-uniformly if necessary such that the image's
+ * viewBox (if specified or implied by height/width attributes) exactly
+ * matches the viewport rectangle.
+ *
+ * FLAG_FORCE_UNIFORM_SCALING: Signal to ClippedImage::OptimalSizeForDest that
+ * its returned size can only scale the image's size *uniformly* (by the same
+ * factor in each dimension). We need this flag when painting border-image
+ * section with SVG image source-data, if the SVG image has no viewBox and no
+ * intrinsic size. In such a case, we synthesize a viewport for the SVG image
+ * (a "window into SVG space") based on the border image area, and we need to
+ * be sure we don't subsequently scale that viewport in a way that distorts
+ * its contents by stretching them more in one dimension than the other.
+ *
+ * FLAG_AVOID_REDECODE_FOR_SIZE: If there is already a raster surface
+ * available for this image, but it is not the same size as requested, skip
+ * starting a new decode for said size.
+ *
+ * FLAG_DECODE_TO_SRGB_COLORSPACE: Instead of converting the colorspace to
+ * the display's colorspace, use sRGB.
+ *
+ * FLAG_RECORD_BLOB: Instead of rasterizing an SVG image on the main thread,
+ * record the drawing commands using blob images.
+ */
+ const unsigned long FLAG_NONE = 0x0;
+ const unsigned long FLAG_SYNC_DECODE = 0x1;
+ const unsigned long FLAG_SYNC_DECODE_IF_FAST = 0x2;
+ const unsigned long FLAG_ASYNC_NOTIFY = 0x4;
+ const unsigned long FLAG_DECODE_NO_PREMULTIPLY_ALPHA = 0x8;
+ const unsigned long FLAG_DECODE_NO_COLORSPACE_CONVERSION = 0x10;
+ const unsigned long FLAG_CLAMP = 0x20;
+ const unsigned long FLAG_HIGH_QUALITY_SCALING = 0x40;
+ const unsigned long FLAG_BYPASS_SURFACE_CACHE = 0x80;
+ const unsigned long FLAG_FORCE_PRESERVEASPECTRATIO_NONE = 0x100;
+ const unsigned long FLAG_FORCE_UNIFORM_SCALING = 0x200;
+ const unsigned long FLAG_AVOID_REDECODE_FOR_SIZE = 0x400;
+ const unsigned long FLAG_DECODE_TO_SRGB_COLORSPACE = 0x800;
+ const unsigned long FLAG_RECORD_BLOB = 0x1000;
+
+ /**
+ * A constant specifying the default set of decode flags (i.e., the default
+ * values for FLAG_DECODE_*).
+ */
+ const unsigned long DECODE_FLAGS_DEFAULT = 0;
+
+ /**
+ * A constant specifying the decode flags recommended to be used when
+ * re-encoding an image, or with the clipboard.
+ */
+ const unsigned long DECODE_FLAGS_FOR_REENCODE =
+ FLAG_DECODE_NO_PREMULTIPLY_ALPHA | FLAG_DECODE_TO_SRGB_COLORSPACE;
+
+ /**
+ * Constants for specifying various "special" frames.
+ *
+ * FRAME_FIRST: The first frame
+ * FRAME_CURRENT: The current frame
+ *
+ * FRAME_MAX_VALUE should be set to the value of the maximum constant above,
+ * as it is used for ensuring that a valid value was passed in.
+ */
+ const unsigned long FRAME_FIRST = 0;
+ const unsigned long FRAME_CURRENT = 1;
+ const unsigned long FRAME_MAX_VALUE = 1;
+
+ /**
+ * Get a surface for the given frame. This may be a platform-native,
+ * optimized surface, so you cannot inspect its pixel data. If you
+ * need that, use SourceSurface::GetDataSurface.
+ *
+ * @param aWhichFrame Frame specifier of the FRAME_* variety.
+ * @param aFlags Flags of the FLAG_* variety
+ */
+ [noscript, notxpcom] TempRefSourceSurface getFrame(in uint32_t aWhichFrame,
+ in uint32_t aFlags);
+
+ /**
+ * Get a surface for the given frame at the specified size. Matching the
+ * requested size is best effort; it's not guaranteed that the surface you get
+ * will be a perfect match. (Some reasons you may get a surface of a different
+ * size include: if you requested upscaling, if downscale-during-decode is
+ * disabled, or if you didn't request the first frame.)
+ *
+ * @param aSize The desired size.
+ * @param aWhichFrame Frame specifier of the FRAME_* variety.
+ * @param aFlags Flags of the FLAG_* variety
+ */
+ [noscript, notxpcom] TempRefSourceSurface getFrameAtSize([const] in nsIntSize aSize,
+ in uint32_t aWhichFrame,
+ in uint32_t aFlags);
+
+ /**
+ * Returns true if this image will draw opaquely right now if asked to draw
+ * with FLAG_HIGH_QUALITY_SCALING and otherwise default flags. If this image
+ * (when decoded) is opaque but no decoded frames are available then
+ * willDrawOpaqueNow will return false.
+ */
+ [noscript, notxpcom] boolean willDrawOpaqueNow();
+
+ /**
+ * Returns true if this image has a frame and the frame currently has a
+ * least 1 decoded pixel. Only valid for raster images.
+ */
+ [noscript, notxpcom] boolean hasDecodedPixels();
+
+ /**
+ * @return true if getImageContainer() is expected to return a valid
+ * ImageContainer when passed the given @Renderer and @Flags
+ * parameters.
+ */
+ [noscript, notxpcom] boolean isImageContainerAvailable(in WindowRenderer aRenderer,
+ in uint32_t aFlags);
+
+ /**
+ * Attempts to find a WebRenderImageProvider containing the current frame at
+ * the given size. Match the requested size is best effort; it's not
+ * guaranteed that the surface you get will be a perfect match. (Some reasons
+ * you may get a surface of a different size include: if you requested
+ * upscaling, or if downscale-during-decode is disabled.)
+ *
+ * @param aRenderer The WindowRenderer which will be used to render the
+ * ImageContainer.
+ * @param aSVGContext If specified, SVG-related rendering context, such as
+ * overridden attributes on the image document's root <svg>
+ * node, and the size of the viewport that the full image
+ * would occupy. Ignored for raster images.
+ * @param aFlags Decoding / drawing flags (in other words, FLAG_* flags).
+ * Currently only FLAG_SYNC_DECODE and FLAG_SYNC_DECODE_IF_FAST
+ * are supported.
+ * @param aProvider Return value for WebRenderImageProvider for the current
+ * frame. May be null depending on the draw result.
+ * @return The draw result for the current frame.
+ */
+ [noscript, notxpcom] ImgDrawResult getImageProvider(in WindowRenderer aRenderer,
+ [const] in nsIntSize aSize,
+ [const] in SVGImageContext aSVGContext,
+ [const] in MaybeImageIntRegion aRegion,
+ in uint32_t aFlags,
+ out WebRenderImageProvider aProvider);
+
+ /**
+ * Draw the requested frame of this image onto the context specified.
+ *
+ * Drawing an image involves scaling it to a certain size (which may be
+ * implemented as a "smart" scale by substituting an HQ-scaled frame or
+ * rendering at a high DPI), and then selecting a region of that image to
+ * draw. That region is drawn onto the graphics context and in the process
+ * transformed by the context matrix, which determines the final area that is
+ * filled. The basic process looks like this:
+ *
+ * +------------------+
+ * | Image |
+ * | |
+ * | intrinsic width |
+ * | X |
+ * | intrinsic height |
+ * +------------------+
+ * / \
+ * / \
+ * / (scale to aSize) \
+ * / \
+ * +----------------------------+
+ * | |
+ * | Scaled Image |
+ * | aSize.width X aSize.height |
+ * | |
+ * | +---------+ |
+ * | | aRegion | |
+ * | +---------+ |
+ * +-------(---------(----------+
+ * | |
+ * / \
+ * | (transform |
+ * / by aContext \
+ * | matrix) |
+ * / \
+ * +---------------------+
+ * | |
+ * | Fill Rect |
+ * | |
+ * +---------------------+
+ *
+ * The region may extend outside of the scaled image's boundaries. It's
+ * actually a region in tiled image space, which is formed by tiling the
+ * scaled image infinitely in every direction. Drawing with a region larger
+ * than the scaled image thus causes the filled area to contain multiple tiled
+ * copies of the image, which looks like this:
+ *
+ * ....................................................
+ * : : : :
+ * : Tile : Tile : Tile :
+ * : +------------[aRegion]------------+ :
+ * :........|.......:................:........|.......:
+ * : | : : | :
+ * : Ti|le : Scaled Image : Ti|le :
+ * : | : : | :
+ * :........|.......:................:........|.......:
+ * : +---------------------------------+ :
+ * : Ti|le : Tile : Ti|le :
+ * : / : : \ :
+ * :......(.........:................:..........).....:
+ * | |
+ * / \
+ * | (transform by aContext matrix) |
+ * / \
+ * +---------------------------------------------+
+ * | : : |
+ * |.....:.................................:.....|
+ * | : : |
+ * | : Tiled Fill : |
+ * | : : |
+ * |.....:.................................:.....|
+ * | : : |
+ * +---------------------------------------------+
+ *
+ *
+ * @param aContext The Thebes context to draw the image to.
+ * @param aSize The size to which the image should be scaled before drawing.
+ * This requirement may be satisfied using HQ scaled frames,
+ * selecting from different resolution layers, drawing at a
+ * higher DPI, or just performing additional scaling on the
+ * graphics context. Callers can use optimalImageSizeForDest()
+ * to determine the best choice for this parameter if they have
+ * no special size requirements.
+ * @param aRegion The region in tiled image space which will be drawn onto the
+ * graphics context. aRegion is in the coordinate space of the
+ * image after it has been scaled to aSize - that is, the image
+ * is scaled first, and then aRegion is applied. When aFlags
+ * includes FLAG_CLAMP, the image will be extended to this area
+ * by clamping image sample coordinates. Otherwise, the image
+ * will be automatically tiled as necessary. aRegion can also
+ * optionally contain a second region which restricts the set
+ * of pixels we're allowed to sample from when drawing; this
+ * is only of use to callers which need to draw with pixel
+ * snapping.
+ * @param aWhichFrame Frame specifier of the FRAME_* variety.
+ * @param aSamplingFilter The filter to be used if we're scaling the image.
+ * @param aSVGContext If specified, SVG-related rendering context, such as
+ * overridden attributes on the image document's root <svg>
+ * node, and the size of the viewport that the full image
+ * would occupy. Ignored for raster images.
+ * @param aFlags Flags of the FLAG_* variety
+ * @return A ImgDrawResult value indicating whether and to what degree the
+ * drawing operation was successful.
+ */
+ [noscript, notxpcom] ImgDrawResult
+ draw(in gfxContext aContext,
+ [const] in nsIntSize aSize,
+ [const] in ImageRegion aRegion,
+ in uint32_t aWhichFrame,
+ in SamplingFilter aSamplingFilter,
+ [const] in SVGImageContext aSVGContext,
+ in uint32_t aFlags,
+ in float aOpacity);
+
+ /*
+ * Ensures that an image is decoding. Calling this function guarantees that
+ * the image will at some point fire off decode notifications. Images that
+ * can be decoded "quickly" according to some heuristic will be decoded
+ * synchronously.
+ *
+ * @param aFlags Flags of the FLAG_* variety. Only FLAG_ASYNC_NOTIFY
+ * is accepted; all others are ignored.
+ * @param aWhichFrame Frame specifier of the FRAME_* variety.
+ */
+ [noscript] void startDecoding(in uint32_t aFlags, in uint32_t aWhichFrame);
+
+%{C++
+ nsresult StartDecoding(uint32_t aFlags) {
+ return StartDecoding(aFlags, FRAME_CURRENT);
+ }
+%}
+
+ /*
+ * Exactly like startDecoding above except returns whether the current frame
+ * of the image is complete or not.
+ *
+ * @param aFlags Flags of the FLAG_* variety. Only FLAG_ASYNC_NOTIFY
+ * is accepted; all others are ignored.
+ * @param aWhichFrame Frame specifier of the FRAME_* variety.
+ */
+ [noscript, notxpcom] boolean startDecodingWithResult(in uint32_t aFlags, in uint32_t aWhichFrame);
+
+%{C++
+ bool StartDecodingWithResult(uint32_t aFlags) {
+ return StartDecodingWithResult(aFlags, FRAME_CURRENT);
+ }
+%}
+
+ /*
+ * This method triggers decoding for an image, but unlike startDecoding() it
+ * enables the caller to provide more detailed information about the decode
+ * request.
+ *
+ * @param aFlags Flags of the FLAG_* variety.
+ * @param aWhichFrame Frame specifier of the FRAME_* variety.
+ * @return DECODE_SURFACE_AVAILABLE if is a surface that satisfies the
+ * request and it is fully decoded.
+ * DECODE_REQUESTED if we requested a decode.
+ * DECODE_REQUEST_FAILED if we failed to request a decode. This means
+ * that either there is an error in the image or we cannot allocate a
+ * surface that big.
+ */
+ cenum DecodeResult : 8 {
+ DECODE_SURFACE_AVAILABLE = 0,
+ DECODE_REQUESTED = 1,
+ DECODE_REQUEST_FAILED = 2
+ };
+ [noscript, notxpcom] imgIContainer_DecodeResult requestDecodeWithResult(in uint32_t aFlags, in uint32_t aWhichFrame);
+
+%{C++
+ DecodeResult RequestDecodeWithResult(uint32_t aFlags) {
+ return RequestDecodeWithResult(aFlags, FRAME_CURRENT);
+ }
+%}
+
+ /*
+ * This method triggers decoding for an image, but unlike startDecoding() it
+ * enables the caller to provide more detailed information about the decode
+ * request.
+ *
+ * @param aSize The size to which the image should be scaled while decoding,
+ * if possible. If the image cannot be scaled to this size while
+ * being decoded, it will be decoded at its intrinsic size.
+ * @param aFlags Flags of the FLAG_* variety.
+ * @param aWhichFrame Frame specifier of the FRAME_* variety.
+ */
+ [noscript] void requestDecodeForSize([const] in nsIntSize aSize,
+ in uint32_t aFlags,
+ in uint32_t aWhichFrame);
+
+%{C++
+ nsresult RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) {
+ return RequestDecodeForSize(aSize, aFlags, FRAME_CURRENT);
+ }
+%}
+
+ /**
+ * Increments the lock count on the image. An image will not be discarded
+ * as long as the lock count is nonzero. Note that it is still possible for
+ * the image to be undecoded if decode-on-draw is enabled and the image
+ * was never drawn.
+ *
+ * Upon instantiation images have a lock count of zero.
+ */
+ void lockImage();
+
+ /**
+ * Decreases the lock count on the image. If the lock count drops to zero,
+ * the image is allowed to discard its frame data to save memory.
+ *
+ * Upon instantiation images have a lock count of zero. It is an error to
+ * call this method without first having made a matching lockImage() call.
+ * In other words, the lock count is not allowed to be negative.
+ */
+ void unlockImage();
+
+ /**
+ * If this image is unlocked, discard its decoded data. If the image is
+ * locked or has already been discarded, do nothing.
+ */
+ void requestDiscard();
+
+ /**
+ * Indicates that this imgIContainer has been triggered to update
+ * its internal animation state. Likely this should only be called
+ * from within nsImageFrame or objects of similar type.
+ */
+ [notxpcom] void requestRefresh([const] in TimeStamp aTime);
+
+ /**
+ * Animation mode Constants
+ * 0 = normal
+ * 1 = don't animate
+ * 2 = loop once
+ */
+ const short kNormalAnimMode = 0;
+ const short kDontAnimMode = 1;
+ const short kLoopOnceAnimMode = 2;
+
+ attribute unsigned short animationMode;
+
+ /* Methods to control animation */
+ void resetAnimation();
+
+ /*
+ * Returns an index for the requested animation frame (either FRAME_FIRST or
+ * FRAME_CURRENT).
+ *
+ * The units of the index aren't specified, and may vary between different
+ * types of images. What you can rely on is that on all occasions when
+ * getFrameIndex(FRAME_CURRENT) returns a certain value,
+ * draw(..FRAME_CURRENT..) will draw the same frame. The same holds for
+ * FRAME_FIRST as well.
+ *
+ * @param aWhichFrame Frame specifier of the FRAME_* variety.
+ */
+ [notxpcom] float getFrameIndex(in uint32_t aWhichFrame);
+
+ /*
+ * Returns the inherent orientation of the image, as described in the image's
+ * metadata (e.g. EXIF).
+ */
+ [notxpcom] Orientation getOrientation();
+
+ /*
+ * Returns the intrinsic resolution of the image, or 1.0 if the image doesn't
+ * declare any.
+ */
+ [notxpcom] ImageResolution getResolution();
+
+ /*
+ * Returns the delay, in ms, between the first and second frame. If this
+ * returns 0, there is no delay between first and second frame (i.e., this
+ * image could render differently whenever it draws).
+ *
+ * If this image is not animated, or not known to be animated (see attribute
+ * animated), returns -1.
+ */
+ [notxpcom] int32_t getFirstFrameDelay();
+
+ /*
+ * If this is an animated image that hasn't started animating already, this
+ * sets the animation's start time to the indicated time.
+ *
+ * This has no effect if the image isn't animated or it has started animating
+ * already; it also has no effect if the image format doesn't care about
+ * animation start time.
+ *
+ * In all cases, animation does not actually begin until startAnimation(),
+ * resetAnimation(), or requestRefresh() is called for the first time.
+ */
+ [notxpcom] void setAnimationStartTime([const] in TimeStamp aTime);
+
+ /*
+ * Given an invalidation rect in the coordinate system used by the decoder,
+ * returns an invalidation rect in image space.
+ *
+ * This is the identity transformation in most cases, but the result can
+ * differ if the image is wrapped by an ImageWrapper that changes its size
+ * or orientation.
+ */
+ [notxpcom] nsIntRectByVal
+ getImageSpaceInvalidationRect([const] in nsIntRect aRect);
+
+ /*
+ * Removes any ImageWrappers and returns the unwrapped base image.
+ */
+ [notxpcom, nostdcall] TempRefImgIContainer unwrap();
+
+ /*
+ * Propagate the use counters (if any) from this container to the passed in
+ * document.
+ */
+ [noscript, notxpcom] void propagateUseCounters(in Document aReferencingDocument);
+
+ /*
+ * Called when media feature values that apply to all documents (such as
+ * those based on system metrics) have changed. If this image is a type
+ * that can respond to media queries (i.e., an SVG image), this function
+ * is overridden to handle restyling and invalidating the image.
+ */
+ [notxpcom, nostdcall] void mediaFeatureValuesChangedAllDocuments([const] in MediaFeatureChange aChange);
+
+ /*
+ * Get the set of sizes the image can decode to natively.
+ */
+ [nostdcall] Array<nsIntSizeByVal> getNativeSizes();
+
+ [nostdcall, notxpcom] size_t getNativeSizesLength();
+};
diff --git a/image/imgIContainerDebug.idl b/image/imgIContainerDebug.idl
new file mode 100644
index 0000000000..426ae1df85
--- /dev/null
+++ b/image/imgIContainerDebug.idl
@@ -0,0 +1,25 @@
+/** -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+/**
+ * This interface is used in debug builds (and only there) in
+ * order to let automatic tests running JavaScript access
+ * internal state of imgContainers. This lets us test
+ * things like animation.
+ */
+[scriptable, builtinclass, uuid(52cbb839-6e63-4a70-b21a-1db4ca706c49)]
+interface imgIContainerDebug : nsISupports
+{
+ /**
+ * The # of frames this imgContainer has been notified about.
+ * That is equal to the # of times the animation timer has
+ * fired, and is usually equal to the # of frames actually
+ * drawn (but actual drawing might be disabled).
+ */
+ readonly attribute uint32_t framesNotified;
+};
diff --git a/image/imgIEncoder.idl b/image/imgIEncoder.idl
new file mode 100644
index 0000000000..c458b9cf4c
--- /dev/null
+++ b/image/imgIEncoder.idl
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+#include "nsIAsyncInputStream.idl"
+#include "nsIEventTarget.idl"
+
+/**
+ * imgIEncoder interface
+ */
+[scriptable, builtinclass, uuid(4baa2d6e-fee7-42df-ae3f-5fbebc0c267c)]
+interface imgIEncoder : nsIAsyncInputStream
+{
+ // Possible values for outputOptions. Multiple values are semicolon-separated.
+ //
+ // PNG:
+ // ----
+ // transparency=[yes|no|none] -- default: "yes"
+ // Overrides default from input format. "no" and "none" are equivalent.
+ // png-zlib-level=[0-9] -- default: "3"
+ // Overrides default from compression level for zlib.
+ // png-filter=[no_filters|none|sub|up|avg|paeth|fast|all] -- default: "sub"
+ // Overrides default filter.
+ //
+ //
+ // APNG:
+ // -----
+ // The following options can be used with startImageEncode():
+ //
+ // transparency=[yes|no|none] -- default: "yes"
+ // Overrides default from input format. "no" and "none" are equivalent.
+ // skipfirstframe=[yes|no] -- default: "no"
+ // Controls display of the first frame in animations. PNG-only clients
+ // always display the first frame (and only that frame).
+ // frames=# -- default: "1"
+ // Total number of frames in the image. The first frame, even if skipped,
+ // is always included in the count.
+ // plays=# -- default: "0"
+ // Number of times to play the animation sequence. "0" will repeat
+ // forever.
+ //
+ // The following options can be used for each frame, with addImageFrame():
+ //
+ // transparency=[yes|no|none] -- default: "yes"
+ // Overrides default from input format. "no" and "none" are equivalent.
+ // delay=# -- default: "500"
+ // Number of milliseconds to display the frame, before moving to the next
+ // frame.
+ // dispose=[none|background|previous] -- default: "none"
+ // What to do with the image's canvas before rendering the next frame.
+ // See APNG spec.
+ // blend=[source|over] -- default: "source"
+ // How to render the new frame on the canvas. See APNG spec.
+ // xoffset=# -- default: "0"
+ // yoffset=# -- default: "0"
+ // Where to draw the frame, relative to the canvas.
+ //
+ //
+ // JPEG:
+ // -----
+ //
+ // quality=# -- default: "92"
+ // Quality of compression, 0-100 (worst-best).
+ // Quality >= 90 prevents down-sampling of the color channels.
+ //
+ //
+ // WEBP:
+ // -----
+ //
+ // quality=# -- default: "92"
+ // Quality of compression, 0-100 (worst-best).
+
+
+ // Possible values for input format (note that not all image formats
+ // support saving alpha channels):
+
+ // Input is RGB each pixel is represented by three bytes:
+ // R, G, and B (in that order, regardless of host endianness)
+ const uint32_t INPUT_FORMAT_RGB = 0;
+
+ // Input is RGB each pixel is represented by four bytes:
+ // R, G, and B (in that order, regardless of host endianness).
+ // POST-MULTIPLIED alpha us used (50% transparent red is 0xff000080)
+ const uint32_t INPUT_FORMAT_RGBA = 1;
+
+ // Input is host-endian ARGB: On big-endian machines each pixel is therefore
+ // ARGB, and for little-endian machiens (Intel) each pixel is BGRA
+ // (This is used by canvas to match it's internal representation)
+ //
+ // PRE-MULTIPLIED alpha is used (That is, 50% transparent red is 0x80800000,
+ // not 0x80ff0000
+ const uint32_t INPUT_FORMAT_HOSTARGB = 2;
+
+ /* data - list of bytes in the format specified by inputFormat
+ * width - width in pixels
+ * height - height in pixels
+ * stride - number of bytes per row in the image
+ * Normally (width*3) or (width*4), depending on your input format,
+ * but some data uses padding at the end of each row, which would
+ * be extra.
+ * inputFormat - one of INPUT_FORMAT_* specifying the format of data
+ * outputOptions - semicolon-delimited list of name=value pairs that can
+ * give options to the output encoder. Options are encoder-
+ * specific. Just give empty string for default behavior.
+ */
+ void initFromData([array, size_is(length), const] in uint8_t data,
+ in unsigned long length,
+ in uint32_t width,
+ in uint32_t height,
+ in uint32_t stride,
+ in uint32_t inputFormat,
+ in AString outputOptions);
+
+ /*
+ * For encoding images which may contain multiple frames, the 1-shot
+ * initFromData() interface is too simplistic. The alternative is to
+ * use startImageEncode(), call addImageFrame() one or more times, and
+ * then finish initialization with endImageEncode().
+ *
+ * The arguments are basically the same as in initFromData().
+ */
+ void startImageEncode(in uint32_t width,
+ in uint32_t height,
+ in uint32_t inputFormat,
+ in AString outputOptions);
+
+ void addImageFrame( [array, size_is(length), const] in uint8_t data,
+ in unsigned long length,
+ in uint32_t width,
+ in uint32_t height,
+ in uint32_t stride,
+ in uint32_t frameFormat,
+ in AString frameOptions);
+
+ void endImageEncode();
+
+ /*
+ * Sometimes an encoder can contain another encoder and direct access
+ * to its buffer is necessary. It is only safe to assume that the buffer
+ * returned from getImageBuffer() is of size equal to getImageBufferUsed().
+ */
+ [noscript] unsigned long getImageBufferUsed();
+ [noscript] charPtr getImageBuffer();
+};
diff --git a/image/imgILoader.idl b/image/imgILoader.idl
new file mode 100644
index 0000000000..a8514790a0
--- /dev/null
+++ b/image/imgILoader.idl
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface imgINotificationObserver;
+interface imgIRequest;
+
+interface nsIChannel;
+interface nsILoadGroup;
+interface nsIPrincipal;
+interface nsIStreamListener;
+interface nsIURI;
+interface nsIReferrerInfo;
+
+interface nsISimpleEnumerator;
+
+webidl Document;
+
+#include "nsIRequest.idl" // for nsLoadFlags
+#include "nsIContentPolicy.idl" // for nsContentPolicyType
+
+/**
+ * imgILoader interface
+ *
+ * @author Stuart Parmenter <pavlov@netscape.com>
+ * @version 0.3
+ * @see imagelib2
+ */
+[scriptable, builtinclass, uuid(e61377d2-910e-4c65-a64b-428d150e1fd1)]
+interface imgILoader : nsISupports
+{
+ // Extra flags to pass to loadImage if you want a load to use CORS
+ // validation.
+ const unsigned long LOAD_CORS_ANONYMOUS = 1 << 16;
+ const unsigned long LOAD_CORS_USE_CREDENTIALS = 1 << 17;
+
+ /**
+ * Start the load and decode of an image.
+ * @param aURI the URI to load
+ * @param aInitialDocumentURI the URI that 'initiated' the load -- used for
+ * 3rd party cookie blocking
+ * @param aReferrerInfo the referrer info to compute sending referrer.
+ * @param aLoadingPrincipal the principal of the loading document
+ * @param aLoadGroup Loadgroup to put the image load into
+ * @param aObserver the observer (may be null)
+ * @param aLoadingDocument loading document
+ * @param aLoadFlags Load flags for the request
+ * @param aCacheKey cache key to use for a load if the original
+ * image came from a request that had post data
+ * @param aContentPolicyType [optional] the nsContentPolicyType to
+ * use for this load. Defaults to
+ * nsIContentPolicy::TYPE_IMAGE
+
+
+ * ImageLib does NOT keep a strong ref to the observer; this prevents
+ * reference cycles. This means that callers of loadImage should
+ * make sure to Cancel() the resulting request before the observer
+ * goes away.
+ */
+ imgIRequest loadImageXPCOM(in nsIURI aURI,
+ in nsIURI aInitialDocumentURL,
+ in nsIReferrerInfo aReferrerInfo,
+ in nsIPrincipal aLoadingPrincipal,
+ in nsILoadGroup aLoadGroup,
+ in imgINotificationObserver aObserver,
+ in Document aLoadingDocument,
+ in nsLoadFlags aLoadFlags,
+ in nsISupports cacheKey,
+ [optional]
+ in nsContentPolicyType aContentPolicyType);
+
+ /**
+ * Start the load and decode of an image.
+ * @param aChannel the channel to load the image from. This must
+ * already be opened before this method is called, and there
+ * must have been no OnDataAvailable calls for it yet.
+ * @param aObserver the observer (may be null)
+ * @param aLoadingDocument loading document
+ * @param aListener [out]
+ * A listener that you must send the channel's notifications and data
+ * to. Can be null, in which case imagelib has found a cached image
+ * and is not interested in the data. @aChannel will be canceled for
+ * you in this case.
+ *
+ * ImageLib does NOT keep a strong ref to the observer; this prevents
+ * reference cycles. This means that callers of loadImageWithChannel should
+ * make sure to Cancel() the resulting request before the observer goes away.
+ */
+ imgIRequest loadImageWithChannelXPCOM(in nsIChannel aChannel,
+ in imgINotificationObserver aObserver,
+ in Document aLoadingDocument,
+ out nsIStreamListener aListener);
+};
diff --git a/image/imgINotificationObserver.idl b/image/imgINotificationObserver.idl
new file mode 100644
index 0000000000..bf65713227
--- /dev/null
+++ b/image/imgINotificationObserver.idl
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface imgIRequest;
+
+%{C++
+#include "nsRect.h"
+%}
+
+[ptr] native nsIntRect(nsIntRect);
+
+[scriptable, builtinclass, uuid(03da5641-a333-454a-a859-036d0bb683b7)]
+interface imgINotificationObserver : nsISupports
+{
+ // GetWidth() and GetHeight() can now be used to retrieve the size of the
+ // image.
+ const long SIZE_AVAILABLE = 1;
+
+ // A region of the image (indicated by the |aRect| argument to |notify|) has
+ // changed, and needs to be redrawn. This is triggered both for incremental
+ // rendering as the image gets decoded and for changes due to animation.
+ const long FRAME_UPDATE = 2;
+
+ // The first frame of the image is now decoded and ready to draw.
+ const long FRAME_COMPLETE = 3;
+
+ // The entire image has been loaded. That doesn't mean that it has been
+ // decoded, but it does mean that imgIContainer::Draw is guaranteed to succeed
+ // (modulo decode errors, at least) if you specify FLAG_SYNC_DECODE.
+ const long LOAD_COMPLETE = 4;
+
+ // The entire image has been decoded.
+ const long DECODE_COMPLETE = 5;
+
+ // The decoded version of the image has been discarded. Content should never
+ // change as a result of this notification - discarding is an implementation
+ // detail. This notification should normally only be observed by tests.
+ const long DISCARD = 6;
+
+ // The image was drawn without being locked. This notification is part of the
+ // image locking mechanism that prevents visible images from being discarded;
+ // generally only image locking code needs to observe it.
+ const long UNLOCKED_DRAW = 7;
+
+ // The image is animated.
+ const long IS_ANIMATED = 8;
+
+ // The image is transparent.
+ const long HAS_TRANSPARENCY = 9;
+
+ [noscript, notxpcom, nostdcall]
+ void notify(in imgIRequest aProxy, in long aType,
+ [const] in nsIntRect aRect);
+};
diff --git a/image/imgIRequest.idl b/image/imgIRequest.idl
new file mode 100644
index 0000000000..721beb3a5a
--- /dev/null
+++ b/image/imgIRequest.idl
@@ -0,0 +1,276 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+#include "nsIRequest.idl"
+#include "imgIContainer.idl"
+
+//interface imgIContainer;
+interface imgINotificationObserver;
+interface nsIURI;
+interface nsIPrincipal;
+interface nsIReferrerInfo;
+
+/**
+ * imgIRequest interface
+ *
+ * @author Stuart Parmenter <stuart@mozilla.com>
+ * @version 0.1
+ * @see imagelib2
+ */
+[scriptable, builtinclass, uuid(db0a945c-3883-424a-98d0-2ee0523b0255)]
+interface imgIRequest : nsIRequest
+{
+ /**
+ * the image container...
+ * @return the image object associated with the request.
+ * @attention NEED DOCS
+ */
+ readonly attribute imgIContainer image;
+
+ /**
+ * Provider ID for image providers created by this image.
+ */
+ [infallible] readonly attribute unsigned long providerId;
+
+ /**
+ * The principal for the document that loaded this image. Used when trying to
+ * validate a CORS image load.
+ */
+ [infallible] readonly attribute nsIPrincipal triggeringPrincipal;
+
+ /**
+ * Bits set in the return value from imageStatus
+ * @name statusflags
+ *
+ * Meanings:
+ *
+ * STATUS_NONE: Nothing to report.
+ *
+ * STATUS_SIZE_AVAILABLE: We received enough image data
+ * from the network or filesystem that we know the width
+ * and height of the image, and have thus called SetSize()
+ * on the container.
+ *
+ * STATUS_LOAD_COMPLETE: The data has been fully loaded
+ * to memory, but not necessarily fully decoded.
+ *
+ * STATUS_ERROR: An error occurred loading the image.
+ *
+ * STATUS_FRAME_COMPLETE: The first frame has been
+ * completely decoded.
+ *
+ * STATUS_DECODE_COMPLETE: The whole image has been decoded.
+ *
+ * STATUS_IS_ANIMATED: The image is animated.
+ *
+ * STATUS_HAS_TRANSPARENCY: The image is partially or completely transparent.
+ */
+ //@{
+ const long STATUS_NONE = 0x0;
+ const long STATUS_SIZE_AVAILABLE = 0x1;
+ const long STATUS_LOAD_COMPLETE = 0x2;
+ const long STATUS_ERROR = 0x4;
+ const long STATUS_FRAME_COMPLETE = 0x8;
+ const long STATUS_DECODE_COMPLETE = 0x10;
+ const long STATUS_IS_ANIMATED = 0x20;
+ const long STATUS_HAS_TRANSPARENCY = 0x40;
+ //@}
+
+ /**
+ * Status flags of the STATUS_* variety.
+ */
+ readonly attribute unsigned long imageStatus;
+
+ /*
+ * Actual error code that generated a STATUS_ERROR imageStatus
+ * (see xpcom/base/ErrorList.h)
+ */
+ [noscript] readonly attribute nsresult imageErrorCode;
+
+ /**
+ * The URI the image load was started with. Note that this might not be the
+ * actual URI for the image (e.g. if HTTP redirects happened during the
+ * load).
+ */
+ [infallible] readonly attribute nsIURI URI;
+
+ /**
+ * The URI of the resource we ended up loading after all redirects, etc.
+ */
+ readonly attribute nsIURI finalURI;
+
+ readonly attribute imgINotificationObserver notificationObserver;
+
+ readonly attribute string mimeType;
+
+ /**
+ * The filename that should be used when saving the image. This is determined
+ * from the Content-Disposition, if present, or the uri of the image. This
+ * filename should be validated using nsIMIMEService::GetValidFilenameForSaving
+ * before creating the file.
+ */
+ readonly attribute ACString fileName;
+
+ /**
+ * Clone this request; the returned request will have aObserver as the
+ * observer. aObserver will be notified synchronously (before the clone()
+ * call returns) with all the notifications that have already been dispatched
+ * for this image load.
+ */
+ imgIRequest clone(in imgINotificationObserver aObserver);
+
+ /**
+ * The principal gotten from the channel the image was loaded from.
+ */
+ readonly attribute nsIPrincipal imagePrincipal;
+
+ /**
+ * true if the loading of the image required cross-origin redirects.
+ */
+ readonly attribute bool hadCrossOriginRedirects;
+
+ /**
+ * Whether the request is multipart (ie, multipart/x-mixed-replace)
+ */
+ readonly attribute bool multipart;
+
+ /**
+ * The CORS mode that this image was loaded with (a mozilla::CORSMode).
+ */
+ readonly attribute long CORSMode;
+
+ /**
+ * The referrer that this image was loaded with.
+ */
+ readonly attribute nsIReferrerInfo referrerInfo;
+
+ /**
+ * Cancels this request as in nsIRequest::Cancel(); further, also nulls out
+ * decoderObserver so it gets no further notifications from us.
+ *
+ * NOTE: You should not use this in any new code; instead, use cancel(). Note
+ * that cancel() is asynchronous, which means that some time after you call
+ * it, the listener/observer will get an OnStopRequest(). This means that, if
+ * you're the observer, you can't call cancel() from your destructor.
+ */
+ void cancelAndForgetObserver(in nsresult aStatus);
+
+ /**
+ * Requests a synchronous decode for the image.
+ *
+ * imgIContainer has a startDecoding() method, but callers may want to request
+ * a decode before the container has necessarily been instantiated. Calling
+ * startDecoding() on the imgIRequest simply forwards along the request if the
+ * container already exists, or calls it once the container becomes available
+ * if it does not yet exist.
+ */
+ void startDecoding(in uint32_t aFlags);
+
+ /**
+ * Exactly like startDecoding above except returns whether the current frame
+ * of the image is complete or not.
+ *
+ * @param aFlags Flags of the FLAG_* variety. Only FLAG_ASYNC_NOTIFY
+ * is accepted; all others are ignored.
+ */
+ [noscript, notxpcom] boolean startDecodingWithResult(in uint32_t aFlags);
+
+ /**
+ * This method triggers decoding for an image, but unlike startDecoding() it
+ * enables the caller to provide more detailed information about the decode
+ * request.
+ *
+ * @param aFlags Flags of the FLAG_* variety.
+ * @return DECODE_SURFACE_AVAILABLE if is a surface that satisfies the
+ * request and it is fully decoded.
+ * DECODE_REQUESTED if we requested a decode.
+ * DECODE_REQUEST_FAILED if we failed to request a decode. This means
+ * that either there is an error in the image or we cannot allocate a
+ * surface that big.
+ */
+ [noscript, notxpcom] imgIContainer_DecodeResult requestDecodeWithResult(in uint32_t aFlags);
+/*%{C++
+ DecodeResult RequestDecodeWithResult(uint32_t aFlags);
+%}*/
+
+ /**
+ * Returns true if there is a image and the image has a frame and the frame
+ * currently has a least 1 decoded pixel. Only valid for raster images.
+ */
+ [noscript, notxpcom] boolean hasDecodedPixels();
+
+ /**
+ * Locks an image. If the image does not exist yet, locks it once it becomes
+ * available. The lock persists for the lifetime of the imgIRequest (until
+ * unlockImage is called) even if the underlying image changes.
+ *
+ * If you don't call unlockImage() by the time this imgIRequest goes away, it
+ * will be called for you automatically.
+ *
+ * @see imgIContainer::lockImage for documentation of the underlying call.
+ */
+ void lockImage();
+
+ /**
+ * Unlocks an image.
+ *
+ * @see imgIContainer::unlockImage for documentation of the underlying call.
+ */
+ void unlockImage();
+
+ /**
+ * If this image is unlocked, discard the image's decoded data. If the image
+ * is locked or is already discarded, do nothing.
+ */
+ void requestDiscard();
+
+ /**
+ * If this request is for an animated image, the method creates a new
+ * request which contains the current frame of the image.
+ * Otherwise returns the same request.
+ */
+ imgIRequest getStaticRequest();
+
+ /**
+ * Requests that the image animate (if it has an animation).
+ *
+ * @see Image::IncrementAnimationConsumers for documentation of the
+ * underlying call.
+ */
+ void incrementAnimationConsumers();
+
+ /**
+ * Tell the image it can forget about a request that the image animate.
+ *
+ * @see Image::DecrementAnimationConsumers for documentation of the
+ * underlying call.
+ */
+ void decrementAnimationConsumers();
+
+ /**
+ * Request loading priority boost to requested category, each category
+ * of request increases priority only one time.
+ *
+ * CATEGORY_FRAME_INIT: increase priority when the imgRequest is associated
+ * with an nsImageFrame.
+ *
+ * CATEGORY_FRAME_STYLE: increase priority when the imgRequest is for a CSS
+ * background-image, list-style-image, etc. on a ComputedStyle, and a frame
+ * has been assigned this ComputedStyle.
+ *
+ * CATEGORY_SIZE_QUERY: increase priority when size decoding is necessary to
+ * determine the layout size of an associated nsImageFrame.
+ *
+ * CATEGORY_DISPLAY: increase priority when the image is about to be displayed
+ * in the viewport.
+ */
+ const uint32_t CATEGORY_FRAME_INIT = 1 << 0;
+ const uint32_t CATEGORY_FRAME_STYLE = 1 << 1;
+ const uint32_t CATEGORY_SIZE_QUERY = 1 << 2;
+ const uint32_t CATEGORY_DISPLAY = 1 << 3;
+ void boostPriority(in uint32_t aCategory);
+};
diff --git a/image/imgIScriptedNotificationObserver.idl b/image/imgIScriptedNotificationObserver.idl
new file mode 100644
index 0000000000..54769e38fc
--- /dev/null
+++ b/image/imgIScriptedNotificationObserver.idl
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface imgIRequest;
+
+[scriptable, uuid(10be55b3-2029-41a7-a975-538efed250ed)]
+interface imgIScriptedNotificationObserver : nsISupports
+{
+ void sizeAvailable(in imgIRequest aRequest);
+ void frameUpdate(in imgIRequest aRequest);
+ void frameComplete(in imgIRequest aRequest);
+ void loadComplete(in imgIRequest aRequest);
+ void decodeComplete(in imgIRequest aRequest);
+ void discard(in imgIRequest aRequest);
+ void isAnimated(in imgIRequest aRequest);
+ void hasTransparency(in imgIRequest aRequest);
+};
diff --git a/image/imgITools.idl b/image/imgITools.idl
new file mode 100644
index 0000000000..f635f21162
--- /dev/null
+++ b/image/imgITools.idl
@@ -0,0 +1,207 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIChannel;
+interface nsIEventTarget;
+interface nsIInputStream;
+interface nsIURI;
+interface imgIContainer;
+interface imgILoader;
+interface imgICache;
+interface imgIScriptedNotificationObserver;
+interface imgINotificationObserver;
+interface imgIContainerCallback;
+
+webidl Document;
+
+[scriptable, builtinclass, uuid(4c2383a4-931c-484d-8c4a-973590f66e3f)]
+interface imgITools : nsISupports
+{
+ /**
+ * decodeImageFromBuffer
+ * Caller provides an buffer, a buffer size and a mimetype. We read from
+ * the stream and decompress it (according to the specified mime type) and
+ * return the resulting imgIContainer.
+ *
+ * @param aBuffer
+ * Data in memory.
+ * @param aSize
+ * Buffer size.
+ * @param aMimeType
+ * Type of image in the stream.
+ */
+ imgIContainer decodeImageFromBuffer(in string aBuffer,
+ in unsigned long aSize,
+ in ACString aMimeType);
+
+ /**
+ * decodeImageFromArrayBuffer
+ * Caller provides an ArrayBuffer and a mimetype. We read from
+ * the stream and decompress it (according to the specified mime type) and
+ * return the resulting imgIContainer.
+ *
+ * @param aArrayBuffer
+ * An ArrayBuffer.
+ * @param aMimeType
+ * Type of image in the stream.
+ */
+ [implicit_jscontext]
+ imgIContainer decodeImageFromArrayBuffer(in jsval aArrayBuffer,
+ in ACString aMimeType);
+
+ /**
+ * decodeImageFromChannelAsync
+ * See decodeImage. The main difference between this method and decodeImage
+ * is that here the operation is done async on a thread from the decode
+ * pool. When the operation is completed, the callback is executed with the
+ * result.
+ *
+ * @param aURI
+ * The original URI of the image
+ * @param aChannel
+ * Channel to the image to be decoded.
+ * @param aCallback
+ * The callback is executed when the imgContainer is fully created.
+ * @param aObserver
+ * Optional observer for the decoded image, the caller should make
+ * sure the observer is kept alive as long as necessary, as ImageLib
+ * does not keep a strong reference to the observer.
+ */
+ void decodeImageFromChannelAsync(in nsIURI aURI,
+ in nsIChannel aChannel,
+ in imgIContainerCallback aCallback,
+ in imgINotificationObserver aObserver);
+
+ /**
+ * decodeImageAsync
+ * See decodeImage. The main difference between this method and decodeImage
+ * is that here the operation is done async on a thread from the decode
+ * pool. When the operation is completed, the callback is executed with the
+ * result.
+ *
+ * @param aStream
+ * An input stream for an encoded image file.
+ * @param aMimeType
+ * Type of image in the stream.
+ * @param aCallback
+ * The callback is executed when the imgContainer is fully created.
+ * @param aEventTarget
+ * This eventTarget is used to execute aCallback
+ */
+ void decodeImageAsync(in nsIInputStream aStream,
+ in ACString aMimeType,
+ in imgIContainerCallback aCallback,
+ in nsIEventTarget aEventTarget);
+
+ /**
+ * encodeImage
+ * Caller provides an image container, and the mime type it should be
+ * encoded to. We return an input stream for the encoded image data.
+ *
+ * @param aContainer
+ * An image container.
+ * @param aMimeType
+ * Type of encoded image desired (eg "image/png").
+ * @param outputOptions
+ * Encoder-specific output options.
+ */
+ nsIInputStream encodeImage(in imgIContainer aContainer,
+ in ACString aMimeType,
+ [optional] in AString outputOptions);
+
+ /**
+ * encodeScaledImage
+ * Caller provides an image container, and the mime type it should be
+ * encoded to. We return an input stream for the encoded image data.
+ * The encoded image is scaled to the specified dimensions.
+ *
+ * @param aContainer
+ * An image container.
+ * @param aMimeType
+ * Type of encoded image desired (eg "image/png").
+ * @param aWidth, aHeight
+ * The size (in pixels) desired for the resulting image. Specify 0 to
+ * use the given image's width or height. Values must be >= 0.
+ * @param outputOptions
+ * Encoder-specific output options.
+ */
+ nsIInputStream encodeScaledImage(in imgIContainer aContainer,
+ in ACString aMimeType,
+ in long aWidth,
+ in long aHeight,
+ [optional] in AString outputOptions);
+
+ /**
+ * getImgLoaderForDocument
+ * Retrieve an image loader that reflects the privacy status of the given
+ * document.
+ *
+ * @param doc
+ * A document. Must not be null.
+ */
+ imgILoader getImgLoaderForDocument(in Document doc);
+
+ /**
+ * getImgLoaderForDocument
+ * Retrieve an image cache that reflects the privacy status of the given
+ * document.
+ *
+ * @param doc
+ * A document. Null is allowed, but must _only_ be passed
+ * when there is no way to obtain a relevant document for
+ * the current context in which a cache is desired.
+ */
+ imgICache getImgCacheForDocument(in Document doc);
+
+ /**
+ * encodeCroppedImage
+ * Caller provides an image container, and the mime type it should be
+ * encoded to. We return an input stream for the encoded image data.
+ * The encoded image is cropped to the specified dimensions.
+ *
+ * The given offset and size must not exceed the image bounds.
+ *
+ * @param aContainer
+ * An image container.
+ * @param aMimeType
+ * Type of encoded image desired (eg "image/png").
+ * @param aOffsetX, aOffsetY
+ * The crop offset (in pixels). Values must be >= 0.
+ * @param aWidth, aHeight
+ * The size (in pixels) desired for the resulting image. Specify 0 to
+ * use the given image's width or height. Values must be >= 0.
+ * @param outputOptions
+ * Encoder-specific output options.
+ */
+ nsIInputStream encodeCroppedImage(in imgIContainer aContainer,
+ in ACString aMimeType,
+ in long aOffsetX,
+ in long aOffsetY,
+ in long aWidth,
+ in long aHeight,
+ [optional] in AString outputOptions);
+
+ /**
+ * Create a wrapper around a scripted notification observer (ordinarily
+ * imgINotificationObserver cannot be implemented from scripts).
+ *
+ * @param aObserver The scripted observer to wrap
+ */
+ imgINotificationObserver
+ createScriptedObserver(in imgIScriptedNotificationObserver aObserver);
+};
+
+/**
+ * This is a companion interface for nsIAsyncInputStream::asyncWait.
+ */
+[function, scriptable, uuid(f195772c-a4c0-47ae-80ca-211e001c67be)]
+interface imgIContainerCallback : nsISupports
+{
+ /* If the operation fails, aStatus will contain the error value */
+ void onImageReady(in imgIContainer aImage, in nsresult aStatus);
+};
diff --git a/image/imgLoader.cpp b/image/imgLoader.cpp
new file mode 100644
index 0000000000..dcfb031789
--- /dev/null
+++ b/image/imgLoader.cpp
@@ -0,0 +1,3334 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Undefine windows version of LoadImage because our code uses that name.
+#include "mozilla/ScopeExit.h"
+#include "nsIChildChannel.h"
+#undef LoadImage
+
+#include "imgLoader.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "DecoderFactory.h"
+#include "Image.h"
+#include "ImageLogging.h"
+#include "ReferrerInfo.h"
+#include "imgRequestProxy.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/BasePrincipal.h"
+#include "mozilla/ChaosMode.h"
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/LoadInfo.h"
+#include "mozilla/NullPrincipal.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/ProfilerLabels.h"
+#include "mozilla/StaticPrefs_image.h"
+#include "mozilla/StaticPrefs_network.h"
+#include "mozilla/StoragePrincipalHelper.h"
+#include "mozilla/dom/ContentParent.h"
+#include "mozilla/dom/nsMixedContentBlocker.h"
+#include "mozilla/image/ImageMemoryReporter.h"
+#include "mozilla/layers/CompositorManagerChild.h"
+#include "nsCOMPtr.h"
+#include "nsCRT.h"
+#include "nsComponentManagerUtils.h"
+#include "nsContentPolicyUtils.h"
+#include "nsContentSecurityManager.h"
+#include "nsContentUtils.h"
+#include "nsHttpChannel.h"
+#include "nsIAsyncVerifyRedirectCallback.h"
+#include "nsICacheInfoChannel.h"
+#include "nsIChannelEventSink.h"
+#include "nsIClassOfService.h"
+#include "nsIEffectiveTLDService.h"
+#include "nsIFile.h"
+#include "nsIFileURL.h"
+#include "nsIHttpChannel.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIMemoryReporter.h"
+#include "nsINetworkPredictor.h"
+#include "nsIProgressEventSink.h"
+#include "nsIProtocolHandler.h"
+#include "nsImageModule.h"
+#include "nsMediaSniffer.h"
+#include "nsMimeTypes.h"
+#include "nsNetCID.h"
+#include "nsNetUtil.h"
+#include "nsProxyRelease.h"
+#include "nsQueryObject.h"
+#include "nsReadableUtils.h"
+#include "nsStreamUtils.h"
+#include "prtime.h"
+
+// we want to explore making the document own the load group
+// so we can associate the document URI with the load group.
+// until this point, we have an evil hack:
+#include "nsIHttpChannelInternal.h"
+#include "nsILoadGroupChild.h"
+#include "nsIDocShell.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+using namespace mozilla::image;
+using namespace mozilla::net;
+
+MOZ_DEFINE_MALLOC_SIZE_OF(ImagesMallocSizeOf)
+
+class imgMemoryReporter final : public nsIMemoryReporter {
+ ~imgMemoryReporter() = default;
+
+ public:
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
+ nsISupports* aData, bool aAnonymize) override {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ layers::CompositorManagerChild* manager =
+ mozilla::layers::CompositorManagerChild::GetInstance();
+ if (!manager || !StaticPrefs::image_mem_debug_reporting()) {
+ layers::SharedSurfacesMemoryReport sharedSurfaces;
+ FinishCollectReports(aHandleReport, aData, aAnonymize, sharedSurfaces);
+ return NS_OK;
+ }
+
+ RefPtr<imgMemoryReporter> self(this);
+ nsCOMPtr<nsIHandleReportCallback> handleReport(aHandleReport);
+ nsCOMPtr<nsISupports> data(aData);
+ manager->SendReportSharedSurfacesMemory(
+ [=](layers::SharedSurfacesMemoryReport aReport) {
+ self->FinishCollectReports(handleReport, data, aAnonymize, aReport);
+ },
+ [=](mozilla::ipc::ResponseRejectReason&& aReason) {
+ layers::SharedSurfacesMemoryReport sharedSurfaces;
+ self->FinishCollectReports(handleReport, data, aAnonymize,
+ sharedSurfaces);
+ });
+ return NS_OK;
+ }
+
+ void FinishCollectReports(
+ nsIHandleReportCallback* aHandleReport, nsISupports* aData,
+ bool aAnonymize, layers::SharedSurfacesMemoryReport& aSharedSurfaces) {
+ nsTArray<ImageMemoryCounter> chrome;
+ nsTArray<ImageMemoryCounter> content;
+ nsTArray<ImageMemoryCounter> uncached;
+
+ for (uint32_t i = 0; i < mKnownLoaders.Length(); i++) {
+ for (imgCacheEntry* entry : mKnownLoaders[i]->mCache.Values()) {
+ RefPtr<imgRequest> req = entry->GetRequest();
+ RecordCounterForRequest(req, &content, !entry->HasNoProxies());
+ }
+ MutexAutoLock lock(mKnownLoaders[i]->mUncachedImagesMutex);
+ for (RefPtr<imgRequest> req : mKnownLoaders[i]->mUncachedImages) {
+ RecordCounterForRequest(req, &uncached, req->HasConsumers());
+ }
+ }
+
+ // Note that we only need to anonymize content image URIs.
+
+ ReportCounterArray(aHandleReport, aData, chrome, "images/chrome",
+ /* aAnonymize */ false, aSharedSurfaces);
+
+ ReportCounterArray(aHandleReport, aData, content, "images/content",
+ aAnonymize, aSharedSurfaces);
+
+ // Uncached images may be content or chrome, so anonymize them.
+ ReportCounterArray(aHandleReport, aData, uncached, "images/uncached",
+ aAnonymize, aSharedSurfaces);
+
+ // Report any shared surfaces that were not merged with the surface cache.
+ ImageMemoryReporter::ReportSharedSurfaces(aHandleReport, aData,
+ aSharedSurfaces);
+
+ nsCOMPtr<nsIMemoryReporterManager> imgr =
+ do_GetService("@mozilla.org/memory-reporter-manager;1");
+ if (imgr) {
+ imgr->EndReport();
+ }
+ }
+
+ static int64_t ImagesContentUsedUncompressedDistinguishedAmount() {
+ size_t n = 0;
+ for (uint32_t i = 0; i < imgLoader::sMemReporter->mKnownLoaders.Length();
+ i++) {
+ for (imgCacheEntry* entry :
+ imgLoader::sMemReporter->mKnownLoaders[i]->mCache.Values()) {
+ if (entry->HasNoProxies()) {
+ continue;
+ }
+
+ RefPtr<imgRequest> req = entry->GetRequest();
+ RefPtr<image::Image> image = req->GetImage();
+ if (!image) {
+ continue;
+ }
+
+ // Both this and EntryImageSizes measure
+ // images/content/raster/used/decoded memory. This function's
+ // measurement is secondary -- the result doesn't go in the "explicit"
+ // tree -- so we use moz_malloc_size_of instead of ImagesMallocSizeOf to
+ // prevent DMD from seeing it reported twice.
+ SizeOfState state(moz_malloc_size_of);
+ ImageMemoryCounter counter(req, image, state, /* aIsUsed = */ true);
+
+ n += counter.Values().DecodedHeap();
+ n += counter.Values().DecodedNonHeap();
+ n += counter.Values().DecodedUnknown();
+ }
+ }
+ return n;
+ }
+
+ void RegisterLoader(imgLoader* aLoader) {
+ mKnownLoaders.AppendElement(aLoader);
+ }
+
+ void UnregisterLoader(imgLoader* aLoader) {
+ mKnownLoaders.RemoveElement(aLoader);
+ }
+
+ private:
+ nsTArray<imgLoader*> mKnownLoaders;
+
+ struct MemoryTotal {
+ MemoryTotal& operator+=(const ImageMemoryCounter& aImageCounter) {
+ if (aImageCounter.Type() == imgIContainer::TYPE_RASTER) {
+ if (aImageCounter.IsUsed()) {
+ mUsedRasterCounter += aImageCounter.Values();
+ } else {
+ mUnusedRasterCounter += aImageCounter.Values();
+ }
+ } else if (aImageCounter.Type() == imgIContainer::TYPE_VECTOR) {
+ if (aImageCounter.IsUsed()) {
+ mUsedVectorCounter += aImageCounter.Values();
+ } else {
+ mUnusedVectorCounter += aImageCounter.Values();
+ }
+ } else if (aImageCounter.Type() == imgIContainer::TYPE_REQUEST) {
+ // Nothing to do, we did not get to the point of having an image.
+ } else {
+ MOZ_CRASH("Unexpected image type");
+ }
+
+ return *this;
+ }
+
+ const MemoryCounter& UsedRaster() const { return mUsedRasterCounter; }
+ const MemoryCounter& UnusedRaster() const { return mUnusedRasterCounter; }
+ const MemoryCounter& UsedVector() const { return mUsedVectorCounter; }
+ const MemoryCounter& UnusedVector() const { return mUnusedVectorCounter; }
+
+ private:
+ MemoryCounter mUsedRasterCounter;
+ MemoryCounter mUnusedRasterCounter;
+ MemoryCounter mUsedVectorCounter;
+ MemoryCounter mUnusedVectorCounter;
+ };
+
+ // Reports all images of a single kind, e.g. all used chrome images.
+ void ReportCounterArray(nsIHandleReportCallback* aHandleReport,
+ nsISupports* aData,
+ nsTArray<ImageMemoryCounter>& aCounterArray,
+ const char* aPathPrefix, bool aAnonymize,
+ layers::SharedSurfacesMemoryReport& aSharedSurfaces) {
+ MemoryTotal summaryTotal;
+ MemoryTotal nonNotableTotal;
+
+ // Report notable images, and compute total and non-notable aggregate sizes.
+ for (uint32_t i = 0; i < aCounterArray.Length(); i++) {
+ ImageMemoryCounter& counter = aCounterArray[i];
+
+ if (aAnonymize) {
+ counter.URI().Truncate();
+ counter.URI().AppendPrintf("<anonymized-%u>", i);
+ } else {
+ // The URI could be an extremely long data: URI. Truncate if needed.
+ static const size_t max = 256;
+ if (counter.URI().Length() > max) {
+ counter.URI().Truncate(max);
+ counter.URI().AppendLiteral(" (truncated)");
+ }
+ counter.URI().ReplaceChar('/', '\\');
+ }
+
+ summaryTotal += counter;
+
+ if (counter.IsNotable() || StaticPrefs::image_mem_debug_reporting()) {
+ ReportImage(aHandleReport, aData, aPathPrefix, counter,
+ aSharedSurfaces);
+ } else {
+ ImageMemoryReporter::TrimSharedSurfaces(counter, aSharedSurfaces);
+ nonNotableTotal += counter;
+ }
+ }
+
+ // Report non-notable images in aggregate.
+ ReportTotal(aHandleReport, aData, /* aExplicit = */ true, aPathPrefix,
+ "<non-notable images>/", nonNotableTotal);
+
+ // Report a summary in aggregate, outside of the explicit tree.
+ ReportTotal(aHandleReport, aData, /* aExplicit = */ false, aPathPrefix, "",
+ summaryTotal);
+ }
+
+ static void ReportImage(nsIHandleReportCallback* aHandleReport,
+ nsISupports* aData, const char* aPathPrefix,
+ const ImageMemoryCounter& aCounter,
+ layers::SharedSurfacesMemoryReport& aSharedSurfaces) {
+ nsAutoCString pathPrefix("explicit/"_ns);
+ pathPrefix.Append(aPathPrefix);
+
+ switch (aCounter.Type()) {
+ case imgIContainer::TYPE_RASTER:
+ pathPrefix.AppendLiteral("/raster/");
+ break;
+ case imgIContainer::TYPE_VECTOR:
+ pathPrefix.AppendLiteral("/vector/");
+ break;
+ case imgIContainer::TYPE_REQUEST:
+ pathPrefix.AppendLiteral("/request/");
+ break;
+ default:
+ pathPrefix.AppendLiteral("/unknown=");
+ pathPrefix.AppendInt(aCounter.Type());
+ pathPrefix.AppendLiteral("/");
+ break;
+ }
+
+ pathPrefix.Append(aCounter.IsUsed() ? "used/" : "unused/");
+ if (aCounter.IsValidating()) {
+ pathPrefix.AppendLiteral("validating/");
+ }
+ if (aCounter.HasError()) {
+ pathPrefix.AppendLiteral("err/");
+ }
+
+ pathPrefix.AppendLiteral("progress=");
+ pathPrefix.AppendInt(aCounter.Progress(), 16);
+ pathPrefix.AppendLiteral("/");
+
+ pathPrefix.AppendLiteral("image(");
+ pathPrefix.AppendInt(aCounter.IntrinsicSize().width);
+ pathPrefix.AppendLiteral("x");
+ pathPrefix.AppendInt(aCounter.IntrinsicSize().height);
+ pathPrefix.AppendLiteral(", ");
+
+ if (aCounter.URI().IsEmpty()) {
+ pathPrefix.AppendLiteral("<unknown URI>");
+ } else {
+ pathPrefix.Append(aCounter.URI());
+ }
+
+ pathPrefix.AppendLiteral(")/");
+
+ ReportSurfaces(aHandleReport, aData, pathPrefix, aCounter, aSharedSurfaces);
+
+ ReportSourceValue(aHandleReport, aData, pathPrefix, aCounter.Values());
+ }
+
+ static void ReportSurfaces(
+ nsIHandleReportCallback* aHandleReport, nsISupports* aData,
+ const nsACString& aPathPrefix, const ImageMemoryCounter& aCounter,
+ layers::SharedSurfacesMemoryReport& aSharedSurfaces) {
+ for (const SurfaceMemoryCounter& counter : aCounter.Surfaces()) {
+ nsAutoCString surfacePathPrefix(aPathPrefix);
+ switch (counter.Type()) {
+ case SurfaceMemoryCounterType::NORMAL:
+ if (counter.IsLocked()) {
+ surfacePathPrefix.AppendLiteral("locked/");
+ } else {
+ surfacePathPrefix.AppendLiteral("unlocked/");
+ }
+ if (counter.IsFactor2()) {
+ surfacePathPrefix.AppendLiteral("factor2/");
+ }
+ if (counter.CannotSubstitute()) {
+ surfacePathPrefix.AppendLiteral("cannot_substitute/");
+ }
+ break;
+ case SurfaceMemoryCounterType::CONTAINER:
+ surfacePathPrefix.AppendLiteral("container/");
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unknown counter type");
+ break;
+ }
+
+ surfacePathPrefix.AppendLiteral("types=");
+ surfacePathPrefix.AppendInt(counter.Values().SurfaceTypes(), 16);
+ surfacePathPrefix.AppendLiteral("/surface(");
+ surfacePathPrefix.AppendInt(counter.Key().Size().width);
+ surfacePathPrefix.AppendLiteral("x");
+ surfacePathPrefix.AppendInt(counter.Key().Size().height);
+
+ if (!counter.IsFinished()) {
+ surfacePathPrefix.AppendLiteral(", incomplete");
+ }
+
+ if (counter.Values().ExternalHandles() > 0) {
+ surfacePathPrefix.AppendLiteral(", handles:");
+ surfacePathPrefix.AppendInt(
+ uint32_t(counter.Values().ExternalHandles()));
+ }
+
+ ImageMemoryReporter::AppendSharedSurfacePrefix(surfacePathPrefix, counter,
+ aSharedSurfaces);
+
+ PlaybackType playback = counter.Key().Playback();
+ if (playback == PlaybackType::eAnimated) {
+ if (StaticPrefs::image_mem_debug_reporting()) {
+ surfacePathPrefix.AppendPrintf(
+ " (animation %4u)", uint32_t(counter.Values().FrameIndex()));
+ } else {
+ surfacePathPrefix.AppendLiteral(" (animation)");
+ }
+ }
+
+ if (counter.Key().Flags() != DefaultSurfaceFlags()) {
+ surfacePathPrefix.AppendLiteral(", flags:");
+ surfacePathPrefix.AppendInt(uint32_t(counter.Key().Flags()),
+ /* aRadix = */ 16);
+ }
+
+ if (counter.Key().Region()) {
+ const ImageIntRegion& region = counter.Key().Region().ref();
+ const gfx::IntRect& rect = region.Rect();
+ surfacePathPrefix.AppendLiteral(", region:[ rect=(");
+ surfacePathPrefix.AppendInt(rect.x);
+ surfacePathPrefix.AppendLiteral(",");
+ surfacePathPrefix.AppendInt(rect.y);
+ surfacePathPrefix.AppendLiteral(") ");
+ surfacePathPrefix.AppendInt(rect.width);
+ surfacePathPrefix.AppendLiteral("x");
+ surfacePathPrefix.AppendInt(rect.height);
+ if (region.IsRestricted()) {
+ const gfx::IntRect& restrict = region.Restriction();
+ if (restrict == rect) {
+ surfacePathPrefix.AppendLiteral(", restrict=rect");
+ } else {
+ surfacePathPrefix.AppendLiteral(", restrict=(");
+ surfacePathPrefix.AppendInt(restrict.x);
+ surfacePathPrefix.AppendLiteral(",");
+ surfacePathPrefix.AppendInt(restrict.y);
+ surfacePathPrefix.AppendLiteral(") ");
+ surfacePathPrefix.AppendInt(restrict.width);
+ surfacePathPrefix.AppendLiteral("x");
+ surfacePathPrefix.AppendInt(restrict.height);
+ }
+ }
+ if (region.GetExtendMode() != gfx::ExtendMode::CLAMP) {
+ surfacePathPrefix.AppendLiteral(", extendMode=");
+ surfacePathPrefix.AppendInt(int32_t(region.GetExtendMode()));
+ }
+ surfacePathPrefix.AppendLiteral("]");
+ }
+
+ const SVGImageContext& context = counter.Key().SVGContext();
+ surfacePathPrefix.AppendLiteral(", svgContext:[ ");
+ if (context.GetViewportSize()) {
+ const CSSIntSize& size = context.GetViewportSize().ref();
+ surfacePathPrefix.AppendLiteral("viewport=(");
+ surfacePathPrefix.AppendInt(size.width);
+ surfacePathPrefix.AppendLiteral("x");
+ surfacePathPrefix.AppendInt(size.height);
+ surfacePathPrefix.AppendLiteral(") ");
+ }
+ if (context.GetPreserveAspectRatio()) {
+ nsAutoString aspect;
+ context.GetPreserveAspectRatio()->ToString(aspect);
+ surfacePathPrefix.AppendLiteral("preserveAspectRatio=(");
+ LossyAppendUTF16toASCII(aspect, surfacePathPrefix);
+ surfacePathPrefix.AppendLiteral(") ");
+ }
+ if (auto scheme = context.GetColorScheme()) {
+ surfacePathPrefix.AppendLiteral("colorScheme=");
+ surfacePathPrefix.AppendInt(int32_t(*scheme));
+ surfacePathPrefix.AppendLiteral(" ");
+ }
+ if (context.GetContextPaint()) {
+ const SVGEmbeddingContextPaint* paint = context.GetContextPaint();
+ surfacePathPrefix.AppendLiteral("contextPaint=(");
+ if (paint->GetFill()) {
+ surfacePathPrefix.AppendLiteral(" fill=");
+ surfacePathPrefix.AppendInt(paint->GetFill()->ToABGR(), 16);
+ }
+ if (paint->GetFillOpacity() != 1.0) {
+ surfacePathPrefix.AppendLiteral(" fillOpa=");
+ surfacePathPrefix.AppendFloat(paint->GetFillOpacity());
+ }
+ if (paint->GetStroke()) {
+ surfacePathPrefix.AppendLiteral(" stroke=");
+ surfacePathPrefix.AppendInt(paint->GetStroke()->ToABGR(), 16);
+ }
+ if (paint->GetStrokeOpacity() != 1.0) {
+ surfacePathPrefix.AppendLiteral(" strokeOpa=");
+ surfacePathPrefix.AppendFloat(paint->GetStrokeOpacity());
+ }
+ surfacePathPrefix.AppendLiteral(" ) ");
+ }
+ surfacePathPrefix.AppendLiteral("]");
+
+ surfacePathPrefix.AppendLiteral(")/");
+
+ ReportValues(aHandleReport, aData, surfacePathPrefix, counter.Values());
+ }
+ }
+
+ static void ReportTotal(nsIHandleReportCallback* aHandleReport,
+ nsISupports* aData, bool aExplicit,
+ const char* aPathPrefix, const char* aPathInfix,
+ const MemoryTotal& aTotal) {
+ nsAutoCString pathPrefix;
+ if (aExplicit) {
+ pathPrefix.AppendLiteral("explicit/");
+ }
+ pathPrefix.Append(aPathPrefix);
+
+ nsAutoCString rasterUsedPrefix(pathPrefix);
+ rasterUsedPrefix.AppendLiteral("/raster/used/");
+ rasterUsedPrefix.Append(aPathInfix);
+ ReportValues(aHandleReport, aData, rasterUsedPrefix, aTotal.UsedRaster());
+
+ nsAutoCString rasterUnusedPrefix(pathPrefix);
+ rasterUnusedPrefix.AppendLiteral("/raster/unused/");
+ rasterUnusedPrefix.Append(aPathInfix);
+ ReportValues(aHandleReport, aData, rasterUnusedPrefix,
+ aTotal.UnusedRaster());
+
+ nsAutoCString vectorUsedPrefix(pathPrefix);
+ vectorUsedPrefix.AppendLiteral("/vector/used/");
+ vectorUsedPrefix.Append(aPathInfix);
+ ReportValues(aHandleReport, aData, vectorUsedPrefix, aTotal.UsedVector());
+
+ nsAutoCString vectorUnusedPrefix(pathPrefix);
+ vectorUnusedPrefix.AppendLiteral("/vector/unused/");
+ vectorUnusedPrefix.Append(aPathInfix);
+ ReportValues(aHandleReport, aData, vectorUnusedPrefix,
+ aTotal.UnusedVector());
+ }
+
+ static void ReportValues(nsIHandleReportCallback* aHandleReport,
+ nsISupports* aData, const nsACString& aPathPrefix,
+ const MemoryCounter& aCounter) {
+ ReportSourceValue(aHandleReport, aData, aPathPrefix, aCounter);
+
+ ReportValue(aHandleReport, aData, KIND_HEAP, aPathPrefix, "decoded-heap",
+ "Decoded image data which is stored on the heap.",
+ aCounter.DecodedHeap());
+
+ ReportValue(aHandleReport, aData, KIND_NONHEAP, aPathPrefix,
+ "decoded-nonheap",
+ "Decoded image data which isn't stored on the heap.",
+ aCounter.DecodedNonHeap());
+
+ // We don't know for certain whether or not it is on the heap, so let's
+ // just report it as non-heap for reporting purposes.
+ ReportValue(aHandleReport, aData, KIND_NONHEAP, aPathPrefix,
+ "decoded-unknown",
+ "Decoded image data which is unknown to be on the heap or not.",
+ aCounter.DecodedUnknown());
+ }
+
+ static void ReportSourceValue(nsIHandleReportCallback* aHandleReport,
+ nsISupports* aData,
+ const nsACString& aPathPrefix,
+ const MemoryCounter& aCounter) {
+ ReportValue(aHandleReport, aData, KIND_HEAP, aPathPrefix, "source",
+ "Raster image source data and vector image documents.",
+ aCounter.Source());
+ }
+
+ static void ReportValue(nsIHandleReportCallback* aHandleReport,
+ nsISupports* aData, int32_t aKind,
+ const nsACString& aPathPrefix,
+ const char* aPathSuffix, const char* aDescription,
+ size_t aValue) {
+ if (aValue == 0) {
+ return;
+ }
+
+ nsAutoCString desc(aDescription);
+ nsAutoCString path(aPathPrefix);
+ path.Append(aPathSuffix);
+
+ aHandleReport->Callback(""_ns, path, aKind, UNITS_BYTES, aValue, desc,
+ aData);
+ }
+
+ static void RecordCounterForRequest(imgRequest* aRequest,
+ nsTArray<ImageMemoryCounter>* aArray,
+ bool aIsUsed) {
+ SizeOfState state(ImagesMallocSizeOf);
+ RefPtr<image::Image> image = aRequest->GetImage();
+ if (image) {
+ ImageMemoryCounter counter(aRequest, image, state, aIsUsed);
+ aArray->AppendElement(std::move(counter));
+ } else {
+ // We can at least record some information about the image from the
+ // request, and mark it as not knowing the image type yet.
+ ImageMemoryCounter counter(aRequest, state, aIsUsed);
+ aArray->AppendElement(std::move(counter));
+ }
+ }
+};
+
+NS_IMPL_ISUPPORTS(imgMemoryReporter, nsIMemoryReporter)
+
+NS_IMPL_ISUPPORTS(nsProgressNotificationProxy, nsIProgressEventSink,
+ nsIChannelEventSink, nsIInterfaceRequestor)
+
+NS_IMETHODIMP
+nsProgressNotificationProxy::OnProgress(nsIRequest* request, int64_t progress,
+ int64_t progressMax) {
+ nsCOMPtr<nsILoadGroup> loadGroup;
+ request->GetLoadGroup(getter_AddRefs(loadGroup));
+
+ nsCOMPtr<nsIProgressEventSink> target;
+ NS_QueryNotificationCallbacks(mOriginalCallbacks, loadGroup,
+ NS_GET_IID(nsIProgressEventSink),
+ getter_AddRefs(target));
+ if (!target) {
+ return NS_OK;
+ }
+ return target->OnProgress(mImageRequest, progress, progressMax);
+}
+
+NS_IMETHODIMP
+nsProgressNotificationProxy::OnStatus(nsIRequest* request, nsresult status,
+ const char16_t* statusArg) {
+ nsCOMPtr<nsILoadGroup> loadGroup;
+ request->GetLoadGroup(getter_AddRefs(loadGroup));
+
+ nsCOMPtr<nsIProgressEventSink> target;
+ NS_QueryNotificationCallbacks(mOriginalCallbacks, loadGroup,
+ NS_GET_IID(nsIProgressEventSink),
+ getter_AddRefs(target));
+ if (!target) {
+ return NS_OK;
+ }
+ return target->OnStatus(mImageRequest, status, statusArg);
+}
+
+NS_IMETHODIMP
+nsProgressNotificationProxy::AsyncOnChannelRedirect(
+ nsIChannel* oldChannel, nsIChannel* newChannel, uint32_t flags,
+ nsIAsyncVerifyRedirectCallback* cb) {
+ // Tell the original original callbacks about it too
+ nsCOMPtr<nsILoadGroup> loadGroup;
+ newChannel->GetLoadGroup(getter_AddRefs(loadGroup));
+ nsCOMPtr<nsIChannelEventSink> target;
+ NS_QueryNotificationCallbacks(mOriginalCallbacks, loadGroup,
+ NS_GET_IID(nsIChannelEventSink),
+ getter_AddRefs(target));
+ if (!target) {
+ cb->OnRedirectVerifyCallback(NS_OK);
+ return NS_OK;
+ }
+
+ // Delegate to |target| if set, reusing |cb|
+ return target->AsyncOnChannelRedirect(oldChannel, newChannel, flags, cb);
+}
+
+NS_IMETHODIMP
+nsProgressNotificationProxy::GetInterface(const nsIID& iid, void** result) {
+ if (iid.Equals(NS_GET_IID(nsIProgressEventSink))) {
+ *result = static_cast<nsIProgressEventSink*>(this);
+ NS_ADDREF_THIS();
+ return NS_OK;
+ }
+ if (iid.Equals(NS_GET_IID(nsIChannelEventSink))) {
+ *result = static_cast<nsIChannelEventSink*>(this);
+ NS_ADDREF_THIS();
+ return NS_OK;
+ }
+ if (mOriginalCallbacks) {
+ return mOriginalCallbacks->GetInterface(iid, result);
+ }
+ return NS_NOINTERFACE;
+}
+
+static void NewRequestAndEntry(bool aForcePrincipalCheckForCacheEntry,
+ imgLoader* aLoader, const ImageCacheKey& aKey,
+ imgRequest** aRequest, imgCacheEntry** aEntry) {
+ RefPtr<imgRequest> request = new imgRequest(aLoader, aKey);
+ RefPtr<imgCacheEntry> entry =
+ new imgCacheEntry(aLoader, request, aForcePrincipalCheckForCacheEntry);
+ aLoader->AddToUncachedImages(request);
+ request.forget(aRequest);
+ entry.forget(aEntry);
+}
+
+static bool ShouldRevalidateEntry(imgCacheEntry* aEntry, nsLoadFlags aFlags,
+ bool aHasExpired) {
+ if (aFlags & nsIRequest::LOAD_BYPASS_CACHE) {
+ return false;
+ }
+ if (aFlags & nsIRequest::VALIDATE_ALWAYS) {
+ return true;
+ }
+ if (aEntry->GetMustValidate()) {
+ return true;
+ }
+ if (aHasExpired) {
+ // The cache entry has expired... Determine whether the stale cache
+ // entry can be used without validation...
+ if (aFlags & (nsIRequest::LOAD_FROM_CACHE | nsIRequest::VALIDATE_NEVER |
+ nsIRequest::VALIDATE_ONCE_PER_SESSION)) {
+ // LOAD_FROM_CACHE, VALIDATE_NEVER and VALIDATE_ONCE_PER_SESSION allow
+ // stale cache entries to be used unless they have been explicitly marked
+ // to indicate that revalidation is necessary.
+ return false;
+ }
+ // Entry is expired, revalidate.
+ return true;
+ }
+ return false;
+}
+
+/* Call content policies on cached images that went through a redirect */
+static bool ShouldLoadCachedImage(imgRequest* aImgRequest,
+ Document* aLoadingDocument,
+ nsIPrincipal* aTriggeringPrincipal,
+ nsContentPolicyType aPolicyType,
+ bool aSendCSPViolationReports) {
+ /* Call content policies on cached images - Bug 1082837
+ * Cached images are keyed off of the first uri in a redirect chain.
+ * Hence content policies don't get a chance to test the intermediate hops
+ * or the final destination. Here we test the final destination using
+ * mFinalURI off of the imgRequest and passing it into content policies.
+ * For Mixed Content Blocker, we do an additional check to determine if any
+ * of the intermediary hops went through an insecure redirect with the
+ * mHadInsecureRedirect flag
+ */
+ bool insecureRedirect = aImgRequest->HadInsecureRedirect();
+ nsCOMPtr<nsIURI> contentLocation;
+ aImgRequest->GetFinalURI(getter_AddRefs(contentLocation));
+ nsresult rv;
+
+ nsCOMPtr<nsIPrincipal> loadingPrincipal =
+ aLoadingDocument ? aLoadingDocument->NodePrincipal()
+ : aTriggeringPrincipal;
+ // If there is no context and also no triggeringPrincipal, then we use a fresh
+ // nullPrincipal as the loadingPrincipal because we can not create a loadinfo
+ // without a valid loadingPrincipal.
+ if (!loadingPrincipal) {
+ loadingPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
+ }
+
+ nsCOMPtr<nsILoadInfo> secCheckLoadInfo = new LoadInfo(
+ loadingPrincipal, aTriggeringPrincipal, aLoadingDocument,
+ nsILoadInfo::SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK, aPolicyType);
+
+ secCheckLoadInfo->SetSendCSPViolationEvents(aSendCSPViolationReports);
+
+ int16_t decision = nsIContentPolicy::REJECT_REQUEST;
+ rv = NS_CheckContentLoadPolicy(contentLocation, secCheckLoadInfo,
+ ""_ns, // mime guess
+ &decision, nsContentUtils::GetContentPolicy());
+ if (NS_FAILED(rv) || !NS_CP_ACCEPTED(decision)) {
+ return false;
+ }
+
+ // We call all Content Policies above, but we also have to call mcb
+ // individually to check the intermediary redirect hops are secure.
+ if (insecureRedirect) {
+ // Bug 1314356: If the image ended up in the cache upgraded by HSTS and the
+ // page uses upgrade-inscure-requests it had an insecure redirect
+ // (http->https). We need to invalidate the image and reload it because
+ // mixed content blocker only bails if upgrade-insecure-requests is set on
+ // the doc and the resource load is http: which would result in an incorrect
+ // mixed content warning.
+ nsCOMPtr<nsIDocShell> docShell =
+ NS_CP_GetDocShellFromContext(ToSupports(aLoadingDocument));
+ if (docShell) {
+ Document* document = docShell->GetDocument();
+ if (document && document->GetUpgradeInsecureRequests(false)) {
+ return false;
+ }
+ }
+
+ if (!aTriggeringPrincipal || !aTriggeringPrincipal->IsSystemPrincipal()) {
+ // reset the decision for mixed content blocker check
+ decision = nsIContentPolicy::REJECT_REQUEST;
+ rv = nsMixedContentBlocker::ShouldLoad(insecureRedirect, contentLocation,
+ secCheckLoadInfo,
+ ""_ns, // mime guess
+ true, // aReportError
+ &decision);
+ if (NS_FAILED(rv) || !NS_CP_ACCEPTED(decision)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+// Returns true if this request is compatible with the given CORS mode on the
+// given loading principal, and false if the request may not be reused due
+// to CORS.
+static bool ValidateCORSMode(imgRequest* aRequest, bool aForcePrincipalCheck,
+ CORSMode aCORSMode,
+ nsIPrincipal* aTriggeringPrincipal) {
+ // If the entry's CORS mode doesn't match, or the CORS mode matches but the
+ // document principal isn't the same, we can't use this request.
+ if (aRequest->GetCORSMode() != aCORSMode) {
+ return false;
+ }
+
+ if (aRequest->GetCORSMode() != CORS_NONE || aForcePrincipalCheck) {
+ nsCOMPtr<nsIPrincipal> otherprincipal = aRequest->GetTriggeringPrincipal();
+
+ // If we previously had a principal, but we don't now, we can't use this
+ // request.
+ if (otherprincipal && !aTriggeringPrincipal) {
+ return false;
+ }
+
+ if (otherprincipal && aTriggeringPrincipal &&
+ !otherprincipal->Equals(aTriggeringPrincipal)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool ValidateSecurityInfo(imgRequest* aRequest,
+ bool aForcePrincipalCheck, CORSMode aCORSMode,
+ nsIPrincipal* aTriggeringPrincipal,
+ Document* aLoadingDocument,
+ nsContentPolicyType aPolicyType) {
+ if (!ValidateCORSMode(aRequest, aForcePrincipalCheck, aCORSMode,
+ aTriggeringPrincipal)) {
+ return false;
+ }
+ // Content Policy Check on Cached Images
+ return ShouldLoadCachedImage(aRequest, aLoadingDocument, aTriggeringPrincipal,
+ aPolicyType,
+ /* aSendCSPViolationReports */ false);
+}
+
+static nsresult NewImageChannel(
+ nsIChannel** aResult,
+ // If aForcePrincipalCheckForCacheEntry is true, then we will
+ // force a principal check even when not using CORS before
+ // assuming we have a cache hit on a cache entry that we
+ // create for this channel. This is an out param that should
+ // be set to true if this channel ends up depending on
+ // aTriggeringPrincipal and false otherwise.
+ bool* aForcePrincipalCheckForCacheEntry, nsIURI* aURI,
+ nsIURI* aInitialDocumentURI, CORSMode aCORSMode,
+ nsIReferrerInfo* aReferrerInfo, nsILoadGroup* aLoadGroup,
+ nsLoadFlags aLoadFlags, nsContentPolicyType aPolicyType,
+ nsIPrincipal* aTriggeringPrincipal, nsINode* aRequestingNode,
+ bool aRespectPrivacy, uint64_t aEarlyHintPreloaderId) {
+ MOZ_ASSERT(aResult);
+
+ nsresult rv;
+ nsCOMPtr<nsIHttpChannel> newHttpChannel;
+
+ nsCOMPtr<nsIInterfaceRequestor> callbacks;
+
+ if (aLoadGroup) {
+ // Get the notification callbacks from the load group for the new channel.
+ //
+ // XXX: This is not exactly correct, because the network request could be
+ // referenced by multiple windows... However, the new channel needs
+ // something. So, using the 'first' notification callbacks is better
+ // than nothing...
+ //
+ aLoadGroup->GetNotificationCallbacks(getter_AddRefs(callbacks));
+ }
+
+ // Pass in a nullptr loadgroup because this is the underlying network
+ // request. This request may be referenced by several proxy image requests
+ // (possibly in different documents).
+ // If all of the proxy requests are canceled then this request should be
+ // canceled too.
+ //
+
+ nsSecurityFlags securityFlags =
+ nsContentSecurityManager::ComputeSecurityFlags(
+ aCORSMode, nsContentSecurityManager::CORSSecurityMapping::
+ CORS_NONE_MAPS_TO_INHERITED_CONTEXT);
+
+ securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
+
+ // Note we are calling NS_NewChannelWithTriggeringPrincipal() here with a
+ // node and a principal. This is for things like background images that are
+ // specified by user stylesheets, where the document is being styled, but
+ // the principal is that of the user stylesheet.
+ if (aRequestingNode && aTriggeringPrincipal) {
+ rv = NS_NewChannelWithTriggeringPrincipal(aResult, aURI, aRequestingNode,
+ aTriggeringPrincipal,
+ securityFlags, aPolicyType,
+ nullptr, // PerformanceStorage
+ nullptr, // loadGroup
+ callbacks, aLoadFlags);
+
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ if (aPolicyType == nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON) {
+ // If this is a favicon loading, we will use the originAttributes from the
+ // triggeringPrincipal as the channel's originAttributes. This allows the
+ // favicon loading from XUL will use the correct originAttributes.
+
+ nsCOMPtr<nsILoadInfo> loadInfo = (*aResult)->LoadInfo();
+ rv = loadInfo->SetOriginAttributes(
+ aTriggeringPrincipal->OriginAttributesRef());
+ }
+ } else {
+ // either we are loading something inside a document, in which case
+ // we should always have a requestingNode, or we are loading something
+ // outside a document, in which case the triggeringPrincipal and
+ // triggeringPrincipal should always be the systemPrincipal.
+ // However, there are exceptions: one is Notifications which create a
+ // channel in the parent process in which case we can't get a
+ // requestingNode.
+ rv = NS_NewChannel(aResult, aURI, nsContentUtils::GetSystemPrincipal(),
+ securityFlags, aPolicyType,
+ nullptr, // nsICookieJarSettings
+ nullptr, // PerformanceStorage
+ nullptr, // loadGroup
+ callbacks, aLoadFlags);
+
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ // Use the OriginAttributes from the loading principal, if one is available,
+ // and adjust the private browsing ID based on what kind of load the caller
+ // has asked us to perform.
+ OriginAttributes attrs;
+ if (aTriggeringPrincipal) {
+ attrs = aTriggeringPrincipal->OriginAttributesRef();
+ }
+ attrs.mPrivateBrowsingId = aRespectPrivacy ? 1 : 0;
+
+ nsCOMPtr<nsILoadInfo> loadInfo = (*aResult)->LoadInfo();
+ rv = loadInfo->SetOriginAttributes(attrs);
+ }
+
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ // only inherit if we have a principal
+ *aForcePrincipalCheckForCacheEntry =
+ aTriggeringPrincipal && nsContentUtils::ChannelShouldInheritPrincipal(
+ aTriggeringPrincipal, aURI,
+ /* aInheritForAboutBlank */ false,
+ /* aForceInherit */ false);
+
+ // Initialize HTTP-specific attributes
+ newHttpChannel = do_QueryInterface(*aResult);
+ if (newHttpChannel) {
+ nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
+ do_QueryInterface(newHttpChannel);
+ NS_ENSURE_TRUE(httpChannelInternal, NS_ERROR_UNEXPECTED);
+ rv = httpChannelInternal->SetDocumentURI(aInitialDocumentURI);
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+ if (aReferrerInfo) {
+ DebugOnly<nsresult> rv = newHttpChannel->SetReferrerInfo(aReferrerInfo);
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+ }
+
+ if (aEarlyHintPreloaderId) {
+ rv = httpChannelInternal->SetEarlyHintPreloaderId(aEarlyHintPreloaderId);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ }
+
+ // Image channels are loaded by default with reduced priority.
+ nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(*aResult);
+ if (p) {
+ uint32_t priority = nsISupportsPriority::PRIORITY_LOW;
+
+ if (aLoadFlags & nsIRequest::LOAD_BACKGROUND) {
+ ++priority; // further reduce priority for background loads
+ }
+
+ p->AdjustPriority(priority);
+ }
+
+ // Create a new loadgroup for this new channel, using the old group as
+ // the parent. The indirection keeps the channel insulated from cancels,
+ // but does allow a way for this revalidation to be associated with at
+ // least one base load group for scheduling/caching purposes.
+
+ nsCOMPtr<nsILoadGroup> loadGroup = do_CreateInstance(NS_LOADGROUP_CONTRACTID);
+ nsCOMPtr<nsILoadGroupChild> childLoadGroup = do_QueryInterface(loadGroup);
+ if (childLoadGroup) {
+ childLoadGroup->SetParentLoadGroup(aLoadGroup);
+ }
+ (*aResult)->SetLoadGroup(loadGroup);
+
+ return NS_OK;
+}
+
+static uint32_t SecondsFromPRTime(PRTime aTime) {
+ return nsContentUtils::SecondsFromPRTime(aTime);
+}
+
+/* static */
+imgCacheEntry::imgCacheEntry(imgLoader* loader, imgRequest* request,
+ bool forcePrincipalCheck)
+ : mLoader(loader),
+ mRequest(request),
+ mDataSize(0),
+ mTouchedTime(SecondsFromPRTime(PR_Now())),
+ mLoadTime(SecondsFromPRTime(PR_Now())),
+ mExpiryTime(0),
+ mMustValidate(false),
+ // We start off as evicted so we don't try to update the cache.
+ // PutIntoCache will set this to false.
+ mEvicted(true),
+ mHasNoProxies(true),
+ mForcePrincipalCheck(forcePrincipalCheck),
+ mHasNotified(false) {}
+
+imgCacheEntry::~imgCacheEntry() {
+ LOG_FUNC(gImgLog, "imgCacheEntry::~imgCacheEntry()");
+}
+
+void imgCacheEntry::Touch(bool updateTime /* = true */) {
+ LOG_SCOPE(gImgLog, "imgCacheEntry::Touch");
+
+ if (updateTime) {
+ mTouchedTime = SecondsFromPRTime(PR_Now());
+ }
+
+ UpdateCache();
+}
+
+void imgCacheEntry::UpdateCache(int32_t diff /* = 0 */) {
+ // Don't update the cache if we've been removed from it or it doesn't care
+ // about our size or usage.
+ if (!Evicted() && HasNoProxies()) {
+ mLoader->CacheEntriesChanged(diff);
+ }
+}
+
+void imgCacheEntry::UpdateLoadTime() {
+ mLoadTime = SecondsFromPRTime(PR_Now());
+}
+
+void imgCacheEntry::SetHasNoProxies(bool hasNoProxies) {
+ if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) {
+ if (hasNoProxies) {
+ LOG_FUNC_WITH_PARAM(gImgLog, "imgCacheEntry::SetHasNoProxies true", "uri",
+ mRequest->CacheKey().URI());
+ } else {
+ LOG_FUNC_WITH_PARAM(gImgLog, "imgCacheEntry::SetHasNoProxies false",
+ "uri", mRequest->CacheKey().URI());
+ }
+ }
+
+ mHasNoProxies = hasNoProxies;
+}
+
+imgCacheQueue::imgCacheQueue() : mDirty(false), mSize(0) {}
+
+void imgCacheQueue::UpdateSize(int32_t diff) { mSize += diff; }
+
+uint32_t imgCacheQueue::GetSize() const { return mSize; }
+
+void imgCacheQueue::Remove(imgCacheEntry* entry) {
+ uint64_t index = mQueue.IndexOf(entry);
+ if (index == queueContainer::NoIndex) {
+ return;
+ }
+
+ mSize -= mQueue[index]->GetDataSize();
+
+ // If the queue is clean and this is the first entry,
+ // then we can efficiently remove the entry without
+ // dirtying the sort order.
+ if (!IsDirty() && index == 0) {
+ std::pop_heap(mQueue.begin(), mQueue.end(), imgLoader::CompareCacheEntries);
+ mQueue.RemoveLastElement();
+ return;
+ }
+
+ // Remove from the middle of the list. This potentially
+ // breaks the binary heap sort order.
+ mQueue.RemoveElementAt(index);
+
+ // If we only have one entry or the queue is empty, though,
+ // then the sort order is still effectively good. Simply
+ // refresh the list to clear the dirty flag.
+ if (mQueue.Length() <= 1) {
+ Refresh();
+ return;
+ }
+
+ // Otherwise we must mark the queue dirty and potentially
+ // trigger an expensive sort later.
+ MarkDirty();
+}
+
+void imgCacheQueue::Push(imgCacheEntry* entry) {
+ mSize += entry->GetDataSize();
+
+ RefPtr<imgCacheEntry> refptr(entry);
+ mQueue.AppendElement(std::move(refptr));
+ // If we're not dirty already, then we can efficiently add this to the
+ // binary heap immediately. This is only O(log n).
+ if (!IsDirty()) {
+ std::push_heap(mQueue.begin(), mQueue.end(),
+ imgLoader::CompareCacheEntries);
+ }
+}
+
+already_AddRefed<imgCacheEntry> imgCacheQueue::Pop() {
+ if (mQueue.IsEmpty()) {
+ return nullptr;
+ }
+ if (IsDirty()) {
+ Refresh();
+ }
+
+ std::pop_heap(mQueue.begin(), mQueue.end(), imgLoader::CompareCacheEntries);
+ RefPtr<imgCacheEntry> entry = mQueue.PopLastElement();
+
+ mSize -= entry->GetDataSize();
+ return entry.forget();
+}
+
+void imgCacheQueue::Refresh() {
+ // Resort the list. This is an O(3 * n) operation and best avoided
+ // if possible.
+ std::make_heap(mQueue.begin(), mQueue.end(), imgLoader::CompareCacheEntries);
+ mDirty = false;
+}
+
+void imgCacheQueue::MarkDirty() { mDirty = true; }
+
+bool imgCacheQueue::IsDirty() { return mDirty; }
+
+uint32_t imgCacheQueue::GetNumElements() const { return mQueue.Length(); }
+
+bool imgCacheQueue::Contains(imgCacheEntry* aEntry) const {
+ return mQueue.Contains(aEntry);
+}
+
+imgCacheQueue::iterator imgCacheQueue::begin() { return mQueue.begin(); }
+
+imgCacheQueue::const_iterator imgCacheQueue::begin() const {
+ return mQueue.begin();
+}
+
+imgCacheQueue::iterator imgCacheQueue::end() { return mQueue.end(); }
+
+imgCacheQueue::const_iterator imgCacheQueue::end() const {
+ return mQueue.end();
+}
+
+nsresult imgLoader::CreateNewProxyForRequest(
+ imgRequest* aRequest, nsIURI* aURI, nsILoadGroup* aLoadGroup,
+ Document* aLoadingDocument, imgINotificationObserver* aObserver,
+ nsLoadFlags aLoadFlags, imgRequestProxy** _retval) {
+ LOG_SCOPE_WITH_PARAM(gImgLog, "imgLoader::CreateNewProxyForRequest",
+ "imgRequest", aRequest);
+
+ /* XXX If we move decoding onto separate threads, we should save off the
+ calling thread here and pass it off to |proxyRequest| so that it call
+ proxy calls to |aObserver|.
+ */
+
+ RefPtr<imgRequestProxy> proxyRequest = new imgRequestProxy();
+
+ /* It is important to call |SetLoadFlags()| before calling |Init()| because
+ |Init()| adds the request to the loadgroup.
+ */
+ proxyRequest->SetLoadFlags(aLoadFlags);
+
+ // init adds itself to imgRequest's list of observers
+ nsresult rv = proxyRequest->Init(aRequest, aLoadGroup, aLoadingDocument, aURI,
+ aObserver);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ proxyRequest.forget(_retval);
+ return NS_OK;
+}
+
+class imgCacheExpirationTracker final
+ : public nsExpirationTracker<imgCacheEntry, 3> {
+ enum { TIMEOUT_SECONDS = 10 };
+
+ public:
+ imgCacheExpirationTracker();
+
+ protected:
+ void NotifyExpired(imgCacheEntry* entry) override;
+};
+
+imgCacheExpirationTracker::imgCacheExpirationTracker()
+ : nsExpirationTracker<imgCacheEntry, 3>(TIMEOUT_SECONDS * 1000,
+ "imgCacheExpirationTracker") {}
+
+void imgCacheExpirationTracker::NotifyExpired(imgCacheEntry* entry) {
+ // Hold on to a reference to this entry, because the expiration tracker
+ // mechanism doesn't.
+ RefPtr<imgCacheEntry> kungFuDeathGrip(entry);
+
+ if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) {
+ RefPtr<imgRequest> req = entry->GetRequest();
+ if (req) {
+ LOG_FUNC_WITH_PARAM(gImgLog, "imgCacheExpirationTracker::NotifyExpired",
+ "entry", req->CacheKey().URI());
+ }
+ }
+
+ // We can be called multiple times on the same entry. Don't do work multiple
+ // times.
+ if (!entry->Evicted()) {
+ entry->Loader()->RemoveFromCache(entry);
+ }
+
+ entry->Loader()->VerifyCacheSizes();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// imgLoader
+///////////////////////////////////////////////////////////////////////////////
+
+double imgLoader::sCacheTimeWeight;
+uint32_t imgLoader::sCacheMaxSize;
+imgMemoryReporter* imgLoader::sMemReporter;
+
+NS_IMPL_ISUPPORTS(imgLoader, imgILoader, nsIContentSniffer, imgICache,
+ nsISupportsWeakReference, nsIObserver)
+
+static imgLoader* gNormalLoader = nullptr;
+static imgLoader* gPrivateBrowsingLoader = nullptr;
+
+/* static */
+already_AddRefed<imgLoader> imgLoader::CreateImageLoader() {
+ // In some cases, such as xpctests, XPCOM modules are not automatically
+ // initialized. We need to make sure that our module is initialized before
+ // we hand out imgLoader instances and code starts using them.
+ mozilla::image::EnsureModuleInitialized();
+
+ RefPtr<imgLoader> loader = new imgLoader();
+ loader->Init();
+
+ return loader.forget();
+}
+
+imgLoader* imgLoader::NormalLoader() {
+ if (!gNormalLoader) {
+ gNormalLoader = CreateImageLoader().take();
+ }
+ return gNormalLoader;
+}
+
+imgLoader* imgLoader::PrivateBrowsingLoader() {
+ if (!gPrivateBrowsingLoader) {
+ gPrivateBrowsingLoader = CreateImageLoader().take();
+ gPrivateBrowsingLoader->RespectPrivacyNotifications();
+ }
+ return gPrivateBrowsingLoader;
+}
+
+imgLoader::imgLoader()
+ : mUncachedImagesMutex("imgLoader::UncachedImages"),
+ mRespectPrivacy(false) {
+ sMemReporter->AddRef();
+ sMemReporter->RegisterLoader(this);
+}
+
+imgLoader::~imgLoader() {
+ ClearImageCache();
+ {
+ // If there are any of our imgRequest's left they are in the uncached
+ // images set, so clear their pointer to us.
+ MutexAutoLock lock(mUncachedImagesMutex);
+ for (RefPtr<imgRequest> req : mUncachedImages) {
+ req->ClearLoader();
+ }
+ }
+ sMemReporter->UnregisterLoader(this);
+ sMemReporter->Release();
+}
+
+void imgLoader::VerifyCacheSizes() {
+#ifdef DEBUG
+ if (!mCacheTracker) {
+ return;
+ }
+
+ uint32_t cachesize = mCache.Count();
+ uint32_t queuesize = mCacheQueue.GetNumElements();
+ uint32_t trackersize = 0;
+ for (nsExpirationTracker<imgCacheEntry, 3>::Iterator it(mCacheTracker.get());
+ it.Next();) {
+ trackersize++;
+ }
+ MOZ_ASSERT(queuesize == trackersize, "Queue and tracker sizes out of sync!");
+ MOZ_ASSERT(queuesize <= cachesize, "Queue has more elements than cache!");
+#endif
+}
+
+void imgLoader::GlobalInit() {
+ sCacheTimeWeight = StaticPrefs::image_cache_timeweight_AtStartup() / 1000.0;
+ int32_t cachesize = StaticPrefs::image_cache_size_AtStartup();
+ sCacheMaxSize = cachesize > 0 ? cachesize : 0;
+
+ sMemReporter = new imgMemoryReporter();
+ RegisterStrongAsyncMemoryReporter(sMemReporter);
+ RegisterImagesContentUsedUncompressedDistinguishedAmount(
+ imgMemoryReporter::ImagesContentUsedUncompressedDistinguishedAmount);
+}
+
+void imgLoader::ShutdownMemoryReporter() {
+ UnregisterImagesContentUsedUncompressedDistinguishedAmount();
+ UnregisterStrongMemoryReporter(sMemReporter);
+}
+
+nsresult imgLoader::InitCache() {
+ nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+ if (!os) {
+ return NS_ERROR_FAILURE;
+ }
+
+ os->AddObserver(this, "memory-pressure", false);
+ os->AddObserver(this, "chrome-flush-caches", false);
+ os->AddObserver(this, "last-pb-context-exited", false);
+ os->AddObserver(this, "profile-before-change", false);
+ os->AddObserver(this, "xpcom-shutdown", false);
+
+ mCacheTracker = MakeUnique<imgCacheExpirationTracker>();
+
+ return NS_OK;
+}
+
+nsresult imgLoader::Init() {
+ InitCache();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgLoader::RespectPrivacyNotifications() {
+ mRespectPrivacy = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgLoader::Observe(nsISupports* aSubject, const char* aTopic,
+ const char16_t* aData) {
+ if (strcmp(aTopic, "memory-pressure") == 0) {
+ MinimizeCache();
+ } else if (strcmp(aTopic, "chrome-flush-caches") == 0) {
+ MinimizeCache();
+ ClearImageCache({ClearOption::ChromeOnly});
+ } else if (strcmp(aTopic, "last-pb-context-exited") == 0) {
+ if (mRespectPrivacy) {
+ ClearImageCache();
+ }
+ } else if (strcmp(aTopic, "profile-before-change") == 0) {
+ mCacheTracker = nullptr;
+ } else if (strcmp(aTopic, "xpcom-shutdown") == 0) {
+ mCacheTracker = nullptr;
+ ShutdownMemoryReporter();
+
+ } else {
+ // (Nothing else should bring us here)
+ MOZ_ASSERT(0, "Invalid topic received");
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgLoader::ClearCache(bool chrome) {
+ if (XRE_IsParentProcess()) {
+ bool privateLoader = this == gPrivateBrowsingLoader;
+ for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) {
+ Unused << cp->SendClearImageCache(privateLoader, chrome);
+ }
+ }
+ ClearOptions options;
+ if (chrome) {
+ options += ClearOption::ChromeOnly;
+ }
+ return ClearImageCache(options);
+}
+
+NS_IMETHODIMP
+imgLoader::RemoveEntriesFromPrincipalInAllProcesses(nsIPrincipal* aPrincipal) {
+ if (!XRE_IsParentProcess()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) {
+ Unused << cp->SendClearImageCacheFromPrincipal(aPrincipal);
+ }
+
+ imgLoader* loader;
+ if (aPrincipal->OriginAttributesRef().mPrivateBrowsingId ==
+ nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID) {
+ loader = imgLoader::NormalLoader();
+ } else {
+ loader = imgLoader::PrivateBrowsingLoader();
+ }
+
+ return loader->RemoveEntriesInternal(aPrincipal, nullptr);
+}
+
+NS_IMETHODIMP
+imgLoader::RemoveEntriesFromBaseDomainInAllProcesses(
+ const nsACString& aBaseDomain) {
+ if (!XRE_IsParentProcess()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) {
+ Unused << cp->SendClearImageCacheFromBaseDomain(aBaseDomain);
+ }
+
+ return RemoveEntriesInternal(nullptr, &aBaseDomain);
+}
+
+nsresult imgLoader::RemoveEntriesInternal(nsIPrincipal* aPrincipal,
+ const nsACString* aBaseDomain) {
+ // Can only clear by either principal or base domain.
+ if ((!aPrincipal && !aBaseDomain) || (aPrincipal && aBaseDomain)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ nsAutoString origin;
+ if (aPrincipal) {
+ nsresult rv = nsContentUtils::GetUTFOrigin(aPrincipal, origin);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ }
+
+ nsCOMPtr<nsIEffectiveTLDService> tldService;
+ AutoTArray<RefPtr<imgCacheEntry>, 128> entriesToBeRemoved;
+
+ // For base domain we only clear the non-chrome cache.
+ for (const auto& entry : mCache) {
+ const auto& key = entry.GetKey();
+
+ const bool shouldRemove = [&] {
+ if (aPrincipal) {
+ if (key.OriginAttributesRef() !=
+ BasePrincipal::Cast(aPrincipal)->OriginAttributesRef()) {
+ return false;
+ }
+
+ nsAutoString imageOrigin;
+ nsresult rv = nsContentUtils::GetUTFOrigin(key.URI(), imageOrigin);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return false;
+ }
+
+ return imageOrigin == origin;
+ }
+
+ if (!aBaseDomain) {
+ return false;
+ }
+ // Clear by baseDomain.
+ nsAutoCString host;
+ nsresult rv = key.URI()->GetHost(host);
+ if (NS_FAILED(rv) || host.IsEmpty()) {
+ return false;
+ }
+
+ if (!tldService) {
+ tldService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
+ }
+ if (NS_WARN_IF(!tldService)) {
+ return false;
+ }
+
+ bool hasRootDomain = false;
+ rv = tldService->HasRootDomain(host, *aBaseDomain, &hasRootDomain);
+ if (NS_SUCCEEDED(rv) && hasRootDomain) {
+ return true;
+ }
+
+ // If we don't get a direct base domain match, also check for cache of
+ // third parties partitioned under aBaseDomain.
+
+ // The isolation key is either just the base domain, or an origin suffix
+ // which contains the partitionKey holding the baseDomain.
+
+ if (key.IsolationKeyRef().Equals(*aBaseDomain)) {
+ return true;
+ }
+
+ // The isolation key does not match the given base domain. It may be an
+ // origin suffix. Parse it into origin attributes.
+ OriginAttributes attrs;
+ if (!attrs.PopulateFromSuffix(key.IsolationKeyRef())) {
+ // Key is not an origin suffix.
+ return false;
+ }
+
+ return StoragePrincipalHelper::PartitionKeyHasBaseDomain(
+ attrs.mPartitionKey, *aBaseDomain);
+ }();
+
+ if (shouldRemove) {
+ entriesToBeRemoved.AppendElement(entry.GetData());
+ }
+ }
+
+ for (auto& entry : entriesToBeRemoved) {
+ if (!RemoveFromCache(entry)) {
+ NS_WARNING(
+ "Couldn't remove an entry from the cache in "
+ "RemoveEntriesInternal()\n");
+ }
+ }
+
+ return NS_OK;
+}
+
+constexpr auto AllCORSModes() {
+ return MakeInclusiveEnumeratedRange(kFirstCORSMode, kLastCORSMode);
+}
+
+NS_IMETHODIMP
+imgLoader::RemoveEntry(nsIURI* aURI, Document* aDoc) {
+ if (!aURI) {
+ return NS_OK;
+ }
+ OriginAttributes attrs;
+ if (aDoc) {
+ attrs = aDoc->NodePrincipal()->OriginAttributesRef();
+ }
+ for (auto corsMode : AllCORSModes()) {
+ ImageCacheKey key(aURI, corsMode, attrs, aDoc);
+ RemoveFromCache(key);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgLoader::FindEntryProperties(nsIURI* uri, Document* aDoc,
+ nsIProperties** _retval) {
+ *_retval = nullptr;
+
+ OriginAttributes attrs;
+ if (aDoc) {
+ nsCOMPtr<nsIPrincipal> principal = aDoc->NodePrincipal();
+ if (principal) {
+ attrs = principal->OriginAttributesRef();
+ }
+ }
+
+ for (auto corsMode : AllCORSModes()) {
+ ImageCacheKey key(uri, corsMode, attrs, aDoc);
+ RefPtr<imgCacheEntry> entry;
+ if (!mCache.Get(key, getter_AddRefs(entry)) || !entry) {
+ continue;
+ }
+ if (mCacheTracker && entry->HasNoProxies()) {
+ mCacheTracker->MarkUsed(entry);
+ }
+ RefPtr<imgRequest> request = entry->GetRequest();
+ if (request) {
+ nsCOMPtr<nsIProperties> properties = request->Properties();
+ properties.forget(_retval);
+ return NS_OK;
+ }
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP_(void)
+imgLoader::ClearCacheForControlledDocument(Document* aDoc) {
+ MOZ_ASSERT(aDoc);
+ AutoTArray<RefPtr<imgCacheEntry>, 128> entriesToBeRemoved;
+ for (const auto& entry : mCache) {
+ const auto& key = entry.GetKey();
+ if (key.ControlledDocument() == aDoc) {
+ entriesToBeRemoved.AppendElement(entry.GetData());
+ }
+ }
+ for (auto& entry : entriesToBeRemoved) {
+ if (!RemoveFromCache(entry)) {
+ NS_WARNING(
+ "Couldn't remove an entry from the cache in "
+ "ClearCacheForControlledDocument()\n");
+ }
+ }
+}
+
+void imgLoader::Shutdown() {
+ NS_IF_RELEASE(gNormalLoader);
+ gNormalLoader = nullptr;
+ NS_IF_RELEASE(gPrivateBrowsingLoader);
+ gPrivateBrowsingLoader = nullptr;
+}
+
+bool imgLoader::PutIntoCache(const ImageCacheKey& aKey, imgCacheEntry* entry) {
+ LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::PutIntoCache", "uri",
+ aKey.URI());
+
+ // Check to see if this request already exists in the cache. If so, we'll
+ // replace the old version.
+ RefPtr<imgCacheEntry> tmpCacheEntry;
+ if (mCache.Get(aKey, getter_AddRefs(tmpCacheEntry)) && tmpCacheEntry) {
+ MOZ_LOG(
+ gImgLog, LogLevel::Debug,
+ ("[this=%p] imgLoader::PutIntoCache -- Element already in the cache",
+ nullptr));
+ RefPtr<imgRequest> tmpRequest = tmpCacheEntry->GetRequest();
+
+ // If it already exists, and we're putting the same key into the cache, we
+ // should remove the old version.
+ MOZ_LOG(gImgLog, LogLevel::Debug,
+ ("[this=%p] imgLoader::PutIntoCache -- Replacing cached element",
+ nullptr));
+
+ RemoveFromCache(aKey);
+ } else {
+ MOZ_LOG(gImgLog, LogLevel::Debug,
+ ("[this=%p] imgLoader::PutIntoCache --"
+ " Element NOT already in the cache",
+ nullptr));
+ }
+
+ mCache.InsertOrUpdate(aKey, RefPtr{entry});
+
+ // We can be called to resurrect an evicted entry.
+ if (entry->Evicted()) {
+ entry->SetEvicted(false);
+ }
+
+ // If we're resurrecting an entry with no proxies, put it back in the
+ // tracker and queue.
+ if (entry->HasNoProxies()) {
+ nsresult addrv = NS_OK;
+
+ if (mCacheTracker) {
+ addrv = mCacheTracker->AddObject(entry);
+ }
+
+ if (NS_SUCCEEDED(addrv)) {
+ mCacheQueue.Push(entry);
+ }
+ }
+
+ RefPtr<imgRequest> request = entry->GetRequest();
+ request->SetIsInCache(true);
+ RemoveFromUncachedImages(request);
+
+ return true;
+}
+
+bool imgLoader::SetHasNoProxies(imgRequest* aRequest, imgCacheEntry* aEntry) {
+ LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::SetHasNoProxies", "uri",
+ aRequest->CacheKey().URI());
+
+ aEntry->SetHasNoProxies(true);
+
+ if (aEntry->Evicted()) {
+ return false;
+ }
+
+ nsresult addrv = NS_OK;
+
+ if (mCacheTracker) {
+ addrv = mCacheTracker->AddObject(aEntry);
+ }
+
+ if (NS_SUCCEEDED(addrv)) {
+ mCacheQueue.Push(aEntry);
+ }
+
+ return true;
+}
+
+bool imgLoader::SetHasProxies(imgRequest* aRequest) {
+ VerifyCacheSizes();
+
+ const ImageCacheKey& key = aRequest->CacheKey();
+
+ LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::SetHasProxies", "uri",
+ key.URI());
+
+ RefPtr<imgCacheEntry> entry;
+ if (mCache.Get(key, getter_AddRefs(entry)) && entry) {
+ // Make sure the cache entry is for the right request
+ RefPtr<imgRequest> entryRequest = entry->GetRequest();
+ if (entryRequest == aRequest && entry->HasNoProxies()) {
+ mCacheQueue.Remove(entry);
+
+ if (mCacheTracker) {
+ mCacheTracker->RemoveObject(entry);
+ }
+
+ entry->SetHasNoProxies(false);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void imgLoader::CacheEntriesChanged(int32_t aSizeDiff /* = 0 */) {
+ // We only need to dirty the queue if there is any sorting
+ // taking place. Empty or single-entry lists can't become
+ // dirty.
+ if (mCacheQueue.GetNumElements() > 1) {
+ mCacheQueue.MarkDirty();
+ }
+ mCacheQueue.UpdateSize(aSizeDiff);
+}
+
+void imgLoader::CheckCacheLimits() {
+ if (mCacheQueue.GetNumElements() == 0) {
+ NS_ASSERTION(mCacheQueue.GetSize() == 0,
+ "imgLoader::CheckCacheLimits -- incorrect cache size");
+ }
+
+ // Remove entries from the cache until we're back at our desired max size.
+ while (mCacheQueue.GetSize() > sCacheMaxSize) {
+ // Remove the first entry in the queue.
+ RefPtr<imgCacheEntry> entry(mCacheQueue.Pop());
+
+ NS_ASSERTION(entry, "imgLoader::CheckCacheLimits -- NULL entry pointer");
+
+ if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) {
+ RefPtr<imgRequest> req = entry->GetRequest();
+ if (req) {
+ LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::CheckCacheLimits",
+ "entry", req->CacheKey().URI());
+ }
+ }
+
+ if (entry) {
+ // We just popped this entry from the queue, so pass AlreadyRemoved
+ // to avoid searching the queue again in RemoveFromCache.
+ RemoveFromCache(entry, QueueState::AlreadyRemoved);
+ }
+ }
+}
+
+bool imgLoader::ValidateRequestWithNewChannel(
+ imgRequest* request, nsIURI* aURI, nsIURI* aInitialDocumentURI,
+ nsIReferrerInfo* aReferrerInfo, nsILoadGroup* aLoadGroup,
+ imgINotificationObserver* aObserver, Document* aLoadingDocument,
+ uint64_t aInnerWindowId, nsLoadFlags aLoadFlags,
+ nsContentPolicyType aLoadPolicyType, imgRequestProxy** aProxyRequest,
+ nsIPrincipal* aTriggeringPrincipal, CORSMode aCORSMode, bool aLinkPreload,
+ uint64_t aEarlyHintPreloaderId, bool* aNewChannelCreated) {
+ // now we need to insert a new channel request object in between the real
+ // request and the proxy that basically delays loading the image until it
+ // gets a 304 or figures out that this needs to be a new request
+
+ nsresult rv;
+
+ // If we're currently in the middle of validating this request, just hand
+ // back a proxy to it; the required work will be done for us.
+ if (imgCacheValidator* validator = request->GetValidator()) {
+ rv = CreateNewProxyForRequest(request, aURI, aLoadGroup, aLoadingDocument,
+ aObserver, aLoadFlags, aProxyRequest);
+ if (NS_FAILED(rv)) {
+ return false;
+ }
+
+ if (*aProxyRequest) {
+ imgRequestProxy* proxy = static_cast<imgRequestProxy*>(*aProxyRequest);
+
+ // We will send notifications from imgCacheValidator::OnStartRequest().
+ // In the mean time, we must defer notifications because we are added to
+ // the imgRequest's proxy list, and we can get extra notifications
+ // resulting from methods such as StartDecoding(). See bug 579122.
+ proxy->MarkValidating();
+
+ if (aLinkPreload) {
+ MOZ_ASSERT(aLoadingDocument);
+ proxy->PrioritizeAsPreload();
+ auto preloadKey = PreloadHashKey::CreateAsImage(
+ aURI, aTriggeringPrincipal, aCORSMode);
+ proxy->NotifyOpen(preloadKey, aLoadingDocument, true);
+ }
+
+ // Attach the proxy without notifying
+ validator->AddProxy(proxy);
+ }
+
+ return true;
+ }
+ // We will rely on Necko to cache this request when it's possible, and to
+ // tell imgCacheValidator::OnStartRequest whether the request came from its
+ // cache.
+ nsCOMPtr<nsIChannel> newChannel;
+ bool forcePrincipalCheck;
+ rv =
+ NewImageChannel(getter_AddRefs(newChannel), &forcePrincipalCheck, aURI,
+ aInitialDocumentURI, aCORSMode, aReferrerInfo, aLoadGroup,
+ aLoadFlags, aLoadPolicyType, aTriggeringPrincipal,
+ aLoadingDocument, mRespectPrivacy, aEarlyHintPreloaderId);
+ if (NS_FAILED(rv)) {
+ return false;
+ }
+
+ if (aNewChannelCreated) {
+ *aNewChannelCreated = true;
+ }
+
+ RefPtr<imgRequestProxy> req;
+ rv = CreateNewProxyForRequest(request, aURI, aLoadGroup, aLoadingDocument,
+ aObserver, aLoadFlags, getter_AddRefs(req));
+ if (NS_FAILED(rv)) {
+ return false;
+ }
+
+ // Make sure that OnStatus/OnProgress calls have the right request set...
+ RefPtr<nsProgressNotificationProxy> progressproxy =
+ new nsProgressNotificationProxy(newChannel, req);
+ if (!progressproxy) {
+ return false;
+ }
+
+ RefPtr<imgCacheValidator> hvc =
+ new imgCacheValidator(progressproxy, this, request, aLoadingDocument,
+ aInnerWindowId, forcePrincipalCheck);
+
+ // Casting needed here to get past multiple inheritance.
+ nsCOMPtr<nsIStreamListener> listener =
+ do_QueryInterface(static_cast<nsIThreadRetargetableStreamListener*>(hvc));
+ NS_ENSURE_TRUE(listener, false);
+
+ // We must set the notification callbacks before setting up the
+ // CORS listener, because that's also interested inthe
+ // notification callbacks.
+ newChannel->SetNotificationCallbacks(hvc);
+
+ request->SetValidator(hvc);
+
+ // We will send notifications from imgCacheValidator::OnStartRequest().
+ // In the mean time, we must defer notifications because we are added to
+ // the imgRequest's proxy list, and we can get extra notifications
+ // resulting from methods such as StartDecoding(). See bug 579122.
+ req->MarkValidating();
+
+ if (aLinkPreload) {
+ MOZ_ASSERT(aLoadingDocument);
+ req->PrioritizeAsPreload();
+ auto preloadKey =
+ PreloadHashKey::CreateAsImage(aURI, aTriggeringPrincipal, aCORSMode);
+ req->NotifyOpen(preloadKey, aLoadingDocument, true);
+ }
+
+ // Add the proxy without notifying
+ hvc->AddProxy(req);
+
+ mozilla::net::PredictorLearn(aURI, aInitialDocumentURI,
+ nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE,
+ aLoadGroup);
+ rv = newChannel->AsyncOpen(listener);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ req->CancelAndForgetObserver(rv);
+ // This will notify any current or future <link preload> tags. Pass the
+ // non-open channel so that we can read loadinfo and referrer info of that
+ // channel.
+ req->NotifyStart(newChannel);
+ // Use the non-channel overload of this method to force the notification to
+ // happen. The preload request has not been assigned a channel.
+ req->NotifyStop(rv);
+ return false;
+ }
+
+ req.forget(aProxyRequest);
+ return true;
+}
+
+void imgLoader::NotifyObserversForCachedImage(
+ imgCacheEntry* aEntry, imgRequest* request, nsIURI* aURI,
+ nsIReferrerInfo* aReferrerInfo, Document* aLoadingDocument,
+ nsIPrincipal* aTriggeringPrincipal, CORSMode aCORSMode,
+ uint64_t aEarlyHintPreloaderId) {
+ if (aEntry->HasNotified()) {
+ return;
+ }
+
+ nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
+
+ if (!obsService->HasObservers("http-on-image-cache-response")) {
+ return;
+ }
+
+ aEntry->SetHasNotified();
+
+ nsCOMPtr<nsIChannel> newChannel;
+ bool forcePrincipalCheck;
+ nsresult rv = NewImageChannel(
+ getter_AddRefs(newChannel), &forcePrincipalCheck, aURI, nullptr,
+ aCORSMode, aReferrerInfo, nullptr, 0,
+ nsIContentPolicy::TYPE_INTERNAL_IMAGE, aTriggeringPrincipal,
+ aLoadingDocument, mRespectPrivacy, aEarlyHintPreloaderId);
+ if (NS_FAILED(rv)) {
+ return;
+ }
+
+ RefPtr<HttpBaseChannel> httpBaseChannel = do_QueryObject(newChannel);
+ if (httpBaseChannel) {
+ httpBaseChannel->SetDummyChannelForImageCache();
+ newChannel->SetContentType(nsDependentCString(request->GetMimeType()));
+ RefPtr<mozilla::image::Image> image = request->GetImage();
+ if (image) {
+ newChannel->SetContentLength(aEntry->GetDataSize());
+ }
+ obsService->NotifyObservers(newChannel, "http-on-image-cache-response",
+ nullptr);
+ }
+}
+
+bool imgLoader::ValidateEntry(
+ imgCacheEntry* aEntry, nsIURI* aURI, nsIURI* aInitialDocumentURI,
+ nsIReferrerInfo* aReferrerInfo, nsILoadGroup* aLoadGroup,
+ imgINotificationObserver* aObserver, Document* aLoadingDocument,
+ nsLoadFlags aLoadFlags, nsContentPolicyType aLoadPolicyType,
+ bool aCanMakeNewChannel, bool* aNewChannelCreated,
+ imgRequestProxy** aProxyRequest, nsIPrincipal* aTriggeringPrincipal,
+ CORSMode aCORSMode, bool aLinkPreload, uint64_t aEarlyHintPreloaderId) {
+ LOG_SCOPE(gImgLog, "imgLoader::ValidateEntry");
+
+ // If the expiration time is zero, then the request has not gotten far enough
+ // to know when it will expire, or we know it will never expire (see
+ // nsContentUtils::GetSubresourceCacheValidationInfo).
+ uint32_t expiryTime = aEntry->GetExpiryTime();
+ bool hasExpired = expiryTime && expiryTime <= SecondsFromPRTime(PR_Now());
+
+ nsresult rv;
+
+ // Special treatment for file URLs - aEntry has expired if file has changed
+ nsCOMPtr<nsIFileURL> fileUrl(do_QueryInterface(aURI));
+ if (fileUrl) {
+ uint32_t lastModTime = aEntry->GetLoadTime();
+
+ nsCOMPtr<nsIFile> theFile;
+ rv = fileUrl->GetFile(getter_AddRefs(theFile));
+ if (NS_SUCCEEDED(rv)) {
+ PRTime fileLastMod;
+ rv = theFile->GetLastModifiedTime(&fileLastMod);
+ if (NS_SUCCEEDED(rv)) {
+ // nsIFile uses millisec, NSPR usec
+ fileLastMod *= 1000;
+ hasExpired = SecondsFromPRTime((PRTime)fileLastMod) > lastModTime;
+ }
+ }
+ }
+
+ RefPtr<imgRequest> request(aEntry->GetRequest());
+
+ if (!request) {
+ return false;
+ }
+
+ if (!ValidateSecurityInfo(request, aEntry->ForcePrincipalCheck(), aCORSMode,
+ aTriggeringPrincipal, aLoadingDocument,
+ aLoadPolicyType)) {
+ return false;
+ }
+
+ // data URIs are immutable and by their nature can't leak data, so we can
+ // just return true in that case. Doing so would mean that shift-reload
+ // doesn't reload data URI documents/images though (which is handy for
+ // debugging during gecko development) so we make an exception in that case.
+ if (aURI->SchemeIs("data") && !(aLoadFlags & nsIRequest::LOAD_BYPASS_CACHE)) {
+ return true;
+ }
+
+ bool validateRequest = false;
+
+ if (!request->CanReuseWithoutValidation(aLoadingDocument)) {
+ // If we would need to revalidate this entry, but we're being told to
+ // bypass the cache, we don't allow this entry to be used.
+ if (aLoadFlags & nsIRequest::LOAD_BYPASS_CACHE) {
+ return false;
+ }
+
+ if (MOZ_UNLIKELY(ChaosMode::isActive(ChaosFeature::ImageCache))) {
+ if (ChaosMode::randomUint32LessThan(4) < 1) {
+ return false;
+ }
+ }
+
+ // Determine whether the cache aEntry must be revalidated...
+ validateRequest = ShouldRevalidateEntry(aEntry, aLoadFlags, hasExpired);
+
+ MOZ_LOG(gImgLog, LogLevel::Debug,
+ ("imgLoader::ValidateEntry validating cache entry. "
+ "validateRequest = %d",
+ validateRequest));
+ } else if (!aLoadingDocument && MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) {
+ MOZ_LOG(gImgLog, LogLevel::Debug,
+ ("imgLoader::ValidateEntry BYPASSING cache validation for %s "
+ "because of NULL loading document",
+ aURI->GetSpecOrDefault().get()));
+ }
+
+ // If the original request is still transferring don't kick off a validation
+ // network request because it is a bit silly to issue a validation request if
+ // the original request hasn't even finished yet. So just return true
+ // indicating the caller can create a new proxy for the request and use it as
+ // is.
+ // This is an optimization but it's also required for correctness. If we don't
+ // do this then when firing the load complete notification for the original
+ // request that can unblock load for the document and then spin the event loop
+ // (see the stack in bug 1641682) which then the OnStartRequest for the
+ // validation request can fire which can call UpdateProxies and can sync
+ // notify on the progress tracker about all existing state, which includes
+ // load complete, so we fire a second load complete notification for the
+ // image.
+ // In addition, we want to validate if the original request encountered
+ // an error for two reasons. The first being if the error was a network error
+ // then trying to re-fetch the image might succeed. The second is more
+ // complicated. We decide if we should fire the load or error event for img
+ // elements depending on if the image has error in its status at the time when
+ // the load complete notification is received, and we set error status on an
+ // image if it encounters a network error or a decode error with no real way
+ // to tell them apart. So if we load an image that will produce a decode error
+ // the first time we will usually fire the load event, and then decode enough
+ // to encounter the decode error and set the error status on the image. The
+ // next time we reference the image in the same document the load complete
+ // notification is replayed and this time the error status from the decode is
+ // already present so we fire the error event instead of the load event. This
+ // is a bug (bug 1645576) that we should fix. In order to avoid that bug in
+ // some cases (specifically the cases when we hit this code and try to
+ // validate the request) we make sure to validate. This avoids the bug because
+ // when the load complete notification arrives the proxy is marked as
+ // validating so it lies about its status and returns nothing.
+ bool requestComplete = false;
+ RefPtr<ProgressTracker> tracker;
+ RefPtr<mozilla::image::Image> image = request->GetImage();
+ if (image) {
+ tracker = image->GetProgressTracker();
+ } else {
+ tracker = request->GetProgressTracker();
+ }
+ if (tracker) {
+ if (tracker->GetProgress() & (FLAG_LOAD_COMPLETE | FLAG_HAS_ERROR)) {
+ requestComplete = true;
+ }
+ }
+ if (!requestComplete) {
+ return true;
+ }
+
+ if (validateRequest && aCanMakeNewChannel) {
+ LOG_SCOPE(gImgLog, "imgLoader::ValidateRequest |cache hit| must validate");
+
+ uint64_t innerWindowID =
+ aLoadingDocument ? aLoadingDocument->InnerWindowID() : 0;
+ return ValidateRequestWithNewChannel(
+ request, aURI, aInitialDocumentURI, aReferrerInfo, aLoadGroup,
+ aObserver, aLoadingDocument, innerWindowID, aLoadFlags, aLoadPolicyType,
+ aProxyRequest, aTriggeringPrincipal, aCORSMode, aLinkPreload,
+ aEarlyHintPreloaderId, aNewChannelCreated);
+ }
+
+ if (!validateRequest) {
+ NotifyObserversForCachedImage(aEntry, request, aURI, aReferrerInfo,
+ aLoadingDocument, aTriggeringPrincipal,
+ aCORSMode, aEarlyHintPreloaderId);
+ }
+
+ return !validateRequest;
+}
+
+bool imgLoader::RemoveFromCache(const ImageCacheKey& aKey) {
+ LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::RemoveFromCache", "uri",
+ aKey.URI());
+ RefPtr<imgCacheEntry> entry;
+ mCache.Remove(aKey, getter_AddRefs(entry));
+ if (entry) {
+ MOZ_ASSERT(!entry->Evicted(), "Evicting an already-evicted cache entry!");
+
+ // Entries with no proxies are in the tracker.
+ if (entry->HasNoProxies()) {
+ if (mCacheTracker) {
+ mCacheTracker->RemoveObject(entry);
+ }
+ mCacheQueue.Remove(entry);
+ }
+
+ entry->SetEvicted(true);
+
+ RefPtr<imgRequest> request = entry->GetRequest();
+ request->SetIsInCache(false);
+ AddToUncachedImages(request);
+
+ return true;
+ }
+ return false;
+}
+
+bool imgLoader::RemoveFromCache(imgCacheEntry* entry, QueueState aQueueState) {
+ LOG_STATIC_FUNC(gImgLog, "imgLoader::RemoveFromCache entry");
+
+ RefPtr<imgRequest> request = entry->GetRequest();
+ if (request) {
+ const ImageCacheKey& key = request->CacheKey();
+ LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::RemoveFromCache",
+ "entry's uri", key.URI());
+
+ mCache.Remove(key);
+
+ if (entry->HasNoProxies()) {
+ LOG_STATIC_FUNC(gImgLog,
+ "imgLoader::RemoveFromCache removing from tracker");
+ if (mCacheTracker) {
+ mCacheTracker->RemoveObject(entry);
+ }
+ // Only search the queue to remove the entry if its possible it might
+ // be in the queue. If we know its not in the queue this would be
+ // wasted work.
+ MOZ_ASSERT_IF(aQueueState == QueueState::AlreadyRemoved,
+ !mCacheQueue.Contains(entry));
+ if (aQueueState == QueueState::MaybeExists) {
+ mCacheQueue.Remove(entry);
+ }
+ }
+
+ entry->SetEvicted(true);
+ request->SetIsInCache(false);
+ AddToUncachedImages(request);
+
+ return true;
+ }
+
+ return false;
+}
+
+nsresult imgLoader::ClearImageCache(ClearOptions aOptions) {
+ const bool chromeOnly = aOptions.contains(ClearOption::ChromeOnly);
+ const auto ShouldRemove = [&](imgCacheEntry* aEntry) {
+ if (chromeOnly) {
+ // TODO: Consider also removing "resource://" etc?
+ RefPtr<imgRequest> request = aEntry->GetRequest();
+ if (!request || !request->CacheKey().URI()->SchemeIs("chrome")) {
+ return false;
+ }
+ }
+ return true;
+ };
+ if (aOptions.contains(ClearOption::UnusedOnly)) {
+ LOG_STATIC_FUNC(gImgLog, "imgLoader::ClearImageCache queue");
+ // We have to make a temporary, since RemoveFromCache removes the element
+ // from the queue, invalidating iterators.
+ nsTArray<RefPtr<imgCacheEntry>> entries(mCacheQueue.GetNumElements());
+ for (auto& entry : mCacheQueue) {
+ if (ShouldRemove(entry)) {
+ entries.AppendElement(entry);
+ }
+ }
+
+ // Iterate in reverse order to minimize array copying.
+ for (auto& entry : entries) {
+ if (!RemoveFromCache(entry)) {
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ MOZ_ASSERT(chromeOnly || mCacheQueue.GetNumElements() == 0);
+ return NS_OK;
+ }
+
+ LOG_STATIC_FUNC(gImgLog, "imgLoader::ClearImageCache table");
+ // We have to make a temporary, since RemoveFromCache removes the element
+ // from the queue, invalidating iterators.
+ const auto entries =
+ ToTArray<nsTArray<RefPtr<imgCacheEntry>>>(mCache.Values());
+ for (const auto& entry : entries) {
+ if (!ShouldRemove(entry)) {
+ continue;
+ }
+ if (!RemoveFromCache(entry)) {
+ return NS_ERROR_FAILURE;
+ }
+ }
+ MOZ_ASSERT(chromeOnly || mCache.IsEmpty());
+ return NS_OK;
+}
+
+void imgLoader::AddToUncachedImages(imgRequest* aRequest) {
+ MutexAutoLock lock(mUncachedImagesMutex);
+ mUncachedImages.Insert(aRequest);
+}
+
+void imgLoader::RemoveFromUncachedImages(imgRequest* aRequest) {
+ MutexAutoLock lock(mUncachedImagesMutex);
+ mUncachedImages.Remove(aRequest);
+}
+
+#define LOAD_FLAGS_CACHE_MASK \
+ (nsIRequest::LOAD_BYPASS_CACHE | nsIRequest::LOAD_FROM_CACHE)
+
+#define LOAD_FLAGS_VALIDATE_MASK \
+ (nsIRequest::VALIDATE_ALWAYS | nsIRequest::VALIDATE_NEVER | \
+ nsIRequest::VALIDATE_ONCE_PER_SESSION)
+
+NS_IMETHODIMP
+imgLoader::LoadImageXPCOM(
+ nsIURI* aURI, nsIURI* aInitialDocumentURI, nsIReferrerInfo* aReferrerInfo,
+ nsIPrincipal* aTriggeringPrincipal, nsILoadGroup* aLoadGroup,
+ imgINotificationObserver* aObserver, Document* aLoadingDocument,
+ nsLoadFlags aLoadFlags, nsISupports* aCacheKey,
+ nsContentPolicyType aContentPolicyType, imgIRequest** _retval) {
+ // Optional parameter, so defaults to 0 (== TYPE_INVALID)
+ if (!aContentPolicyType) {
+ aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE;
+ }
+ imgRequestProxy* proxy;
+ nsresult rv =
+ LoadImage(aURI, aInitialDocumentURI, aReferrerInfo, aTriggeringPrincipal,
+ 0, aLoadGroup, aObserver, aLoadingDocument, aLoadingDocument,
+ aLoadFlags, aCacheKey, aContentPolicyType, u""_ns,
+ /* aUseUrgentStartForChannel */ false, /* aListPreload */ false,
+ 0, &proxy);
+ *_retval = proxy;
+ return rv;
+}
+
+static void MakeRequestStaticIfNeeded(
+ Document* aLoadingDocument, imgRequestProxy** aProxyAboutToGetReturned) {
+ if (!aLoadingDocument || !aLoadingDocument->IsStaticDocument()) {
+ return;
+ }
+
+ if (!*aProxyAboutToGetReturned) {
+ return;
+ }
+
+ RefPtr<imgRequestProxy> proxy = dont_AddRef(*aProxyAboutToGetReturned);
+ *aProxyAboutToGetReturned = nullptr;
+
+ RefPtr<imgRequestProxy> staticProxy =
+ proxy->GetStaticRequest(aLoadingDocument);
+ if (staticProxy != proxy) {
+ proxy->CancelAndForgetObserver(NS_BINDING_ABORTED);
+ proxy = std::move(staticProxy);
+ }
+ proxy.forget(aProxyAboutToGetReturned);
+}
+
+bool imgLoader::IsImageAvailable(nsIURI* aURI,
+ nsIPrincipal* aTriggeringPrincipal,
+ CORSMode aCORSMode, Document* aDocument) {
+ ImageCacheKey key(aURI, aCORSMode,
+ aTriggeringPrincipal->OriginAttributesRef(), aDocument);
+ RefPtr<imgCacheEntry> entry;
+ if (!mCache.Get(key, getter_AddRefs(entry)) || !entry) {
+ return false;
+ }
+ RefPtr<imgRequest> request = entry->GetRequest();
+ if (!request) {
+ return false;
+ }
+ if (nsCOMPtr<nsILoadGroup> docLoadGroup = aDocument->GetDocumentLoadGroup()) {
+ nsLoadFlags requestFlags = nsIRequest::LOAD_NORMAL;
+ docLoadGroup->GetLoadFlags(&requestFlags);
+ if (requestFlags & nsIRequest::LOAD_BYPASS_CACHE) {
+ // If we're bypassing the cache, treat the image as not available.
+ return false;
+ }
+ }
+ return ValidateCORSMode(request, false, aCORSMode, aTriggeringPrincipal);
+}
+
+nsresult imgLoader::LoadImage(
+ nsIURI* aURI, nsIURI* aInitialDocumentURI, nsIReferrerInfo* aReferrerInfo,
+ nsIPrincipal* aTriggeringPrincipal, uint64_t aRequestContextID,
+ nsILoadGroup* aLoadGroup, imgINotificationObserver* aObserver,
+ nsINode* aContext, Document* aLoadingDocument, nsLoadFlags aLoadFlags,
+ nsISupports* aCacheKey, nsContentPolicyType aContentPolicyType,
+ const nsAString& initiatorType, bool aUseUrgentStartForChannel,
+ bool aLinkPreload, uint64_t aEarlyHintPreloaderId,
+ imgRequestProxy** _retval) {
+ VerifyCacheSizes();
+
+ NS_ASSERTION(aURI, "imgLoader::LoadImage -- NULL URI pointer");
+
+ if (!aURI) {
+ return NS_ERROR_NULL_POINTER;
+ }
+
+ auto makeStaticIfNeeded = mozilla::MakeScopeExit(
+ [&] { MakeRequestStaticIfNeeded(aLoadingDocument, _retval); });
+
+ AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING("imgLoader::LoadImage", NETWORK,
+ aURI->GetSpecOrDefault());
+
+ LOG_SCOPE_WITH_PARAM(gImgLog, "imgLoader::LoadImage", "aURI", aURI);
+
+ *_retval = nullptr;
+
+ RefPtr<imgRequest> request;
+
+ nsresult rv;
+ nsLoadFlags requestFlags = nsIRequest::LOAD_NORMAL;
+
+#ifdef DEBUG
+ bool isPrivate = false;
+
+ if (aLoadingDocument) {
+ isPrivate = nsContentUtils::IsInPrivateBrowsing(aLoadingDocument);
+ } else if (aLoadGroup) {
+ isPrivate = nsContentUtils::IsInPrivateBrowsing(aLoadGroup);
+ }
+ MOZ_ASSERT(isPrivate == mRespectPrivacy);
+
+ if (aLoadingDocument) {
+ // The given load group should match that of the document if given. If
+ // that isn't the case, then we need to add more plumbing to ensure we
+ // block the document as well.
+ nsCOMPtr<nsILoadGroup> docLoadGroup =
+ aLoadingDocument->GetDocumentLoadGroup();
+ MOZ_ASSERT(docLoadGroup == aLoadGroup);
+ }
+#endif
+
+ // Get the default load flags from the loadgroup (if possible)...
+ if (aLoadGroup) {
+ aLoadGroup->GetLoadFlags(&requestFlags);
+ }
+ //
+ // Merge the default load flags with those passed in via aLoadFlags.
+ // Currently, *only* the caching, validation and background load flags
+ // are merged...
+ //
+ // The flags in aLoadFlags take precedence over the default flags!
+ //
+ if (aLoadFlags & LOAD_FLAGS_CACHE_MASK) {
+ // Override the default caching flags...
+ requestFlags = (requestFlags & ~LOAD_FLAGS_CACHE_MASK) |
+ (aLoadFlags & LOAD_FLAGS_CACHE_MASK);
+ }
+ if (aLoadFlags & LOAD_FLAGS_VALIDATE_MASK) {
+ // Override the default validation flags...
+ requestFlags = (requestFlags & ~LOAD_FLAGS_VALIDATE_MASK) |
+ (aLoadFlags & LOAD_FLAGS_VALIDATE_MASK);
+ }
+ if (aLoadFlags & nsIRequest::LOAD_BACKGROUND) {
+ // Propagate background loading...
+ requestFlags |= nsIRequest::LOAD_BACKGROUND;
+ }
+ if (aLoadFlags & nsIRequest::LOAD_RECORD_START_REQUEST_DELAY) {
+ requestFlags |= nsIRequest::LOAD_RECORD_START_REQUEST_DELAY;
+ }
+
+ if (aLinkPreload) {
+ // Set background loading if it is <link rel=preload>
+ requestFlags |= nsIRequest::LOAD_BACKGROUND;
+ }
+
+ CORSMode corsmode = CORS_NONE;
+ if (aLoadFlags & imgILoader::LOAD_CORS_ANONYMOUS) {
+ corsmode = CORS_ANONYMOUS;
+ } else if (aLoadFlags & imgILoader::LOAD_CORS_USE_CREDENTIALS) {
+ corsmode = CORS_USE_CREDENTIALS;
+ }
+
+ // Look in the preloaded images of loading document first.
+ if (StaticPrefs::network_preload() && !aLinkPreload && aLoadingDocument) {
+ // All Early Hints preloads are Link preloads, therefore we don't have a
+ // Early Hints preload here
+ MOZ_ASSERT(!aEarlyHintPreloaderId);
+ auto key =
+ PreloadHashKey::CreateAsImage(aURI, aTriggeringPrincipal, corsmode);
+ if (RefPtr<PreloaderBase> preload =
+ aLoadingDocument->Preloads().LookupPreload(key)) {
+ RefPtr<imgRequestProxy> proxy = do_QueryObject(preload);
+ MOZ_ASSERT(proxy);
+
+ MOZ_LOG(gImgLog, LogLevel::Debug,
+ ("[this=%p] imgLoader::LoadImage -- preloaded [proxy=%p]"
+ " [document=%p]\n",
+ this, proxy.get(), aLoadingDocument));
+
+ // Removing the preload for this image to be in parity with Chromium. Any
+ // following regular image request will be reloaded using the regular
+ // path: image cache, http cache, network. Any following `<link
+ // rel=preload as=image>` will start a new image preload that can be
+ // satisfied from http cache or network.
+ //
+ // There is a spec discussion for "preload cache", see
+ // https://github.com/w3c/preload/issues/97. And it is also not clear how
+ // preload image interacts with list of available images, see
+ // https://github.com/whatwg/html/issues/4474.
+ proxy->RemoveSelf(aLoadingDocument);
+ proxy->NotifyUsage(aLoadingDocument);
+
+ imgRequest* request = proxy->GetOwner();
+ nsresult rv =
+ CreateNewProxyForRequest(request, aURI, aLoadGroup, aLoadingDocument,
+ aObserver, requestFlags, _retval);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ imgRequestProxy* newProxy = *_retval;
+ if (imgCacheValidator* validator = request->GetValidator()) {
+ newProxy->MarkValidating();
+ // Attach the proxy without notifying and this will add us to the load
+ // group.
+ validator->AddProxy(newProxy);
+ } else {
+ // It's OK to add here even if the request is done. If it is, it'll send
+ // a OnStopRequest()and the proxy will be removed from the loadgroup in
+ // imgRequestProxy::OnLoadComplete.
+ newProxy->AddToLoadGroup();
+ newProxy->NotifyListener();
+ }
+
+ return NS_OK;
+ }
+ }
+
+ RefPtr<imgCacheEntry> entry;
+
+ // Look in the cache for our URI, and then validate it.
+ // XXX For now ignore aCacheKey. We will need it in the future
+ // for correctly dealing with image load requests that are a result
+ // of post data.
+ OriginAttributes attrs;
+ if (aTriggeringPrincipal) {
+ attrs = aTriggeringPrincipal->OriginAttributesRef();
+ }
+ ImageCacheKey key(aURI, corsmode, attrs, aLoadingDocument);
+ if (mCache.Get(key, getter_AddRefs(entry)) && entry) {
+ bool newChannelCreated = false;
+ if (ValidateEntry(entry, aURI, aInitialDocumentURI, aReferrerInfo,
+ aLoadGroup, aObserver, aLoadingDocument, requestFlags,
+ aContentPolicyType, true, &newChannelCreated, _retval,
+ aTriggeringPrincipal, corsmode, aLinkPreload,
+ aEarlyHintPreloaderId)) {
+ request = entry->GetRequest();
+
+ // If this entry has no proxies, its request has no reference to the
+ // entry.
+ if (entry->HasNoProxies()) {
+ LOG_FUNC_WITH_PARAM(gImgLog,
+ "imgLoader::LoadImage() adding proxyless entry",
+ "uri", key.URI());
+ MOZ_ASSERT(!request->HasCacheEntry(),
+ "Proxyless entry's request has cache entry!");
+ request->SetCacheEntry(entry);
+
+ if (mCacheTracker && entry->GetExpirationState()->IsTracked()) {
+ mCacheTracker->MarkUsed(entry);
+ }
+ }
+
+ entry->Touch();
+
+ if (!newChannelCreated) {
+ // This is ugly but it's needed to report CSP violations. We have 3
+ // scenarios:
+ // - we don't have cache. We are not in this if() stmt. A new channel is
+ // created and that triggers the CSP checks.
+ // - We have a cache entry and this is blocked by CSP directives.
+ DebugOnly<bool> shouldLoad = ShouldLoadCachedImage(
+ request, aLoadingDocument, aTriggeringPrincipal, aContentPolicyType,
+ /* aSendCSPViolationReports */ true);
+ MOZ_ASSERT(shouldLoad);
+ }
+ } else {
+ // We can't use this entry. We'll try to load it off the network, and if
+ // successful, overwrite the old entry in the cache with a new one.
+ entry = nullptr;
+ }
+ }
+
+ // Keep the channel in this scope, so we can adjust its notificationCallbacks
+ // later when we create the proxy.
+ nsCOMPtr<nsIChannel> newChannel;
+ // If we didn't get a cache hit, we need to load from the network.
+ if (!request) {
+ LOG_SCOPE(gImgLog, "imgLoader::LoadImage |cache miss|");
+
+ bool forcePrincipalCheck;
+ rv = NewImageChannel(getter_AddRefs(newChannel), &forcePrincipalCheck, aURI,
+ aInitialDocumentURI, corsmode, aReferrerInfo,
+ aLoadGroup, requestFlags, aContentPolicyType,
+ aTriggeringPrincipal, aContext, mRespectPrivacy,
+ aEarlyHintPreloaderId);
+ if (NS_FAILED(rv)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ MOZ_ASSERT(NS_UsePrivateBrowsing(newChannel) == mRespectPrivacy);
+
+ NewRequestAndEntry(forcePrincipalCheck, this, key, getter_AddRefs(request),
+ getter_AddRefs(entry));
+
+ MOZ_LOG(gImgLog, LogLevel::Debug,
+ ("[this=%p] imgLoader::LoadImage -- Created new imgRequest"
+ " [request=%p]\n",
+ this, request.get()));
+
+ nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(newChannel));
+ if (cos) {
+ if (aUseUrgentStartForChannel && !aLinkPreload) {
+ cos->AddClassFlags(nsIClassOfService::UrgentStart);
+ }
+
+ if (StaticPrefs::network_http_tailing_enabled() &&
+ aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON) {
+ cos->AddClassFlags(nsIClassOfService::Throttleable |
+ nsIClassOfService::Tail);
+ nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(newChannel));
+ if (httpChannel) {
+ Unused << httpChannel->SetRequestContextID(aRequestContextID);
+ }
+ }
+ }
+
+ nsCOMPtr<nsILoadGroup> channelLoadGroup;
+ newChannel->GetLoadGroup(getter_AddRefs(channelLoadGroup));
+ rv = request->Init(aURI, aURI, /* aHadInsecureRedirect = */ false,
+ channelLoadGroup, newChannel, entry, aLoadingDocument,
+ aTriggeringPrincipal, corsmode, aReferrerInfo);
+ if (NS_FAILED(rv)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Add the initiator type for this image load
+ nsCOMPtr<nsITimedChannel> timedChannel = do_QueryInterface(newChannel);
+ if (timedChannel) {
+ timedChannel->SetInitiatorType(initiatorType);
+ }
+
+ // create the proxy listener
+ nsCOMPtr<nsIStreamListener> listener = new ProxyListener(request.get());
+
+ MOZ_LOG(gImgLog, LogLevel::Debug,
+ ("[this=%p] imgLoader::LoadImage -- Calling channel->AsyncOpen()\n",
+ this));
+
+ mozilla::net::PredictorLearn(aURI, aInitialDocumentURI,
+ nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE,
+ aLoadGroup);
+
+ nsresult openRes;
+ openRes = newChannel->AsyncOpen(listener);
+
+ if (NS_FAILED(openRes)) {
+ MOZ_LOG(
+ gImgLog, LogLevel::Debug,
+ ("[this=%p] imgLoader::LoadImage -- AsyncOpen() failed: 0x%" PRIx32
+ "\n",
+ this, static_cast<uint32_t>(openRes)));
+ request->CancelAndAbort(openRes);
+ return openRes;
+ }
+
+ // Try to add the new request into the cache.
+ PutIntoCache(key, entry);
+ } else {
+ LOG_MSG_WITH_PARAM(gImgLog, "imgLoader::LoadImage |cache hit|", "request",
+ request);
+ }
+
+ // If we didn't get a proxy when validating the cache entry, we need to
+ // create one.
+ if (!*_retval) {
+ // ValidateEntry() has three return values: "Is valid," "might be valid --
+ // validating over network", and "not valid." If we don't have a _retval,
+ // we know ValidateEntry is not validating over the network, so it's safe
+ // to SetLoadId here because we know this request is valid for this context.
+ //
+ // Note, however, that this doesn't guarantee the behaviour we want (one
+ // URL maps to the same image on a page) if we load the same image in a
+ // different tab (see bug 528003), because its load id will get re-set, and
+ // that'll cause us to validate over the network.
+ request->SetLoadId(aLoadingDocument);
+
+ LOG_MSG(gImgLog, "imgLoader::LoadImage", "creating proxy request.");
+ rv = CreateNewProxyForRequest(request, aURI, aLoadGroup, aLoadingDocument,
+ aObserver, requestFlags, _retval);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ imgRequestProxy* proxy = *_retval;
+
+ // Make sure that OnStatus/OnProgress calls have the right request set, if
+ // we did create a channel here.
+ if (newChannel) {
+ nsCOMPtr<nsIInterfaceRequestor> requestor(
+ new nsProgressNotificationProxy(newChannel, proxy));
+ if (!requestor) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ newChannel->SetNotificationCallbacks(requestor);
+ }
+
+ if (aLinkPreload) {
+ MOZ_ASSERT(aLoadingDocument);
+ proxy->PrioritizeAsPreload();
+ auto preloadKey =
+ PreloadHashKey::CreateAsImage(aURI, aTriggeringPrincipal, corsmode);
+ proxy->NotifyOpen(preloadKey, aLoadingDocument, true);
+ }
+
+ // Note that it's OK to add here even if the request is done. If it is,
+ // it'll send a OnStopRequest() to the proxy in imgRequestProxy::Notify and
+ // the proxy will be removed from the loadgroup.
+ proxy->AddToLoadGroup();
+
+ // If we're loading off the network, explicitly don't notify our proxy,
+ // because necko (or things called from necko, such as imgCacheValidator)
+ // are going to call our notifications asynchronously, and we can't make it
+ // further asynchronous because observers might rely on imagelib completing
+ // its work between the channel's OnStartRequest and OnStopRequest.
+ if (!newChannel) {
+ proxy->NotifyListener();
+ }
+
+ return rv;
+ }
+
+ NS_ASSERTION(*_retval, "imgLoader::LoadImage -- no return value");
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgLoader::LoadImageWithChannelXPCOM(nsIChannel* channel,
+ imgINotificationObserver* aObserver,
+ Document* aLoadingDocument,
+ nsIStreamListener** listener,
+ imgIRequest** _retval) {
+ nsresult result;
+ imgRequestProxy* proxy;
+ result = LoadImageWithChannel(channel, aObserver, aLoadingDocument, listener,
+ &proxy);
+ *_retval = proxy;
+ return result;
+}
+
+nsresult imgLoader::LoadImageWithChannel(nsIChannel* channel,
+ imgINotificationObserver* aObserver,
+ Document* aLoadingDocument,
+ nsIStreamListener** listener,
+ imgRequestProxy** _retval) {
+ NS_ASSERTION(channel,
+ "imgLoader::LoadImageWithChannel -- NULL channel pointer");
+
+ MOZ_ASSERT(NS_UsePrivateBrowsing(channel) == mRespectPrivacy);
+
+ auto makeStaticIfNeeded = mozilla::MakeScopeExit(
+ [&] { MakeRequestStaticIfNeeded(aLoadingDocument, _retval); });
+
+ LOG_SCOPE(gImgLog, "imgLoader::LoadImageWithChannel");
+ RefPtr<imgRequest> request;
+
+ nsCOMPtr<nsIURI> uri;
+ channel->GetURI(getter_AddRefs(uri));
+
+ NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);
+ nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo();
+
+ OriginAttributes attrs = loadInfo->GetOriginAttributes();
+
+ // TODO: Get a meaningful cors mode from the caller probably?
+ const auto corsMode = CORS_NONE;
+ ImageCacheKey key(uri, corsMode, attrs, aLoadingDocument);
+
+ nsLoadFlags requestFlags = nsIRequest::LOAD_NORMAL;
+ channel->GetLoadFlags(&requestFlags);
+
+ RefPtr<imgCacheEntry> entry;
+
+ if (requestFlags & nsIRequest::LOAD_BYPASS_CACHE) {
+ RemoveFromCache(key);
+ } else {
+ // Look in the cache for our URI, and then validate it.
+ // XXX For now ignore aCacheKey. We will need it in the future
+ // for correctly dealing with image load requests that are a result
+ // of post data.
+ if (mCache.Get(key, getter_AddRefs(entry)) && entry) {
+ // We don't want to kick off another network load. So we ask
+ // ValidateEntry to only do validation without creating a new proxy. If
+ // it says that the entry isn't valid any more, we'll only use the entry
+ // we're getting if the channel is loading from the cache anyways.
+ //
+ // XXX -- should this be changed? it's pretty much verbatim from the old
+ // code, but seems nonsensical.
+ //
+ // Since aCanMakeNewChannel == false, we don't need to pass content policy
+ // type/principal/etc
+
+ nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo();
+ // if there is a loadInfo, use the right contentType, otherwise
+ // default to the internal image type
+ nsContentPolicyType policyType = loadInfo->InternalContentPolicyType();
+
+ if (ValidateEntry(entry, uri, nullptr, nullptr, nullptr, aObserver,
+ aLoadingDocument, requestFlags, policyType, false,
+ nullptr, nullptr, nullptr, corsMode, false, 0)) {
+ request = entry->GetRequest();
+ } else {
+ nsCOMPtr<nsICacheInfoChannel> cacheChan(do_QueryInterface(channel));
+ bool bUseCacheCopy;
+
+ if (cacheChan) {
+ cacheChan->IsFromCache(&bUseCacheCopy);
+ } else {
+ bUseCacheCopy = false;
+ }
+
+ if (!bUseCacheCopy) {
+ entry = nullptr;
+ } else {
+ request = entry->GetRequest();
+ }
+ }
+
+ if (request && entry) {
+ // If this entry has no proxies, its request has no reference to
+ // the entry.
+ if (entry->HasNoProxies()) {
+ LOG_FUNC_WITH_PARAM(
+ gImgLog,
+ "imgLoader::LoadImageWithChannel() adding proxyless entry", "uri",
+ key.URI());
+ MOZ_ASSERT(!request->HasCacheEntry(),
+ "Proxyless entry's request has cache entry!");
+ request->SetCacheEntry(entry);
+
+ if (mCacheTracker && entry->GetExpirationState()->IsTracked()) {
+ mCacheTracker->MarkUsed(entry);
+ }
+ }
+ }
+ }
+ }
+
+ nsCOMPtr<nsILoadGroup> loadGroup;
+ channel->GetLoadGroup(getter_AddRefs(loadGroup));
+
+#ifdef DEBUG
+ if (aLoadingDocument) {
+ // The load group of the channel should always match that of the
+ // document if given. If that isn't the case, then we need to add more
+ // plumbing to ensure we block the document as well.
+ nsCOMPtr<nsILoadGroup> docLoadGroup =
+ aLoadingDocument->GetDocumentLoadGroup();
+ MOZ_ASSERT(docLoadGroup == loadGroup);
+ }
+#endif
+
+ // Filter out any load flags not from nsIRequest
+ requestFlags &= nsIRequest::LOAD_REQUESTMASK;
+
+ nsresult rv = NS_OK;
+ if (request) {
+ // we have this in our cache already.. cancel the current (document) load
+
+ // this should fire an OnStopRequest
+ channel->Cancel(NS_ERROR_PARSED_DATA_CACHED);
+
+ *listener = nullptr; // give them back a null nsIStreamListener
+
+ rv = CreateNewProxyForRequest(request, uri, loadGroup, aLoadingDocument,
+ aObserver, requestFlags, _retval);
+ static_cast<imgRequestProxy*>(*_retval)->NotifyListener();
+ } else {
+ // We use originalURI here to fulfil the imgIRequest contract on GetURI.
+ nsCOMPtr<nsIURI> originalURI;
+ channel->GetOriginalURI(getter_AddRefs(originalURI));
+
+ // XXX(seth): We should be able to just use |key| here, except that |key| is
+ // constructed above with the *current URI* and not the *original URI*. I'm
+ // pretty sure this is a bug, and it's preventing us from ever getting a
+ // cache hit in LoadImageWithChannel when redirects are involved.
+ ImageCacheKey originalURIKey(originalURI, corsMode, attrs,
+ aLoadingDocument);
+
+ // Default to doing a principal check because we don't know who
+ // started that load and whether their principal ended up being
+ // inherited on the channel.
+ NewRequestAndEntry(/* aForcePrincipalCheckForCacheEntry = */ true, this,
+ originalURIKey, getter_AddRefs(request),
+ getter_AddRefs(entry));
+
+ // No principal specified here, because we're not passed one.
+ // In LoadImageWithChannel, the redirects that may have been
+ // associated with this load would have gone through necko.
+ // We only have the final URI in ImageLib and hence don't know
+ // if the request went through insecure redirects. But if it did,
+ // the necko cache should have handled that (since all necko cache hits
+ // including the redirects will go through content policy). Hence, we
+ // can set aHadInsecureRedirect to false here.
+ rv = request->Init(originalURI, uri, /* aHadInsecureRedirect = */ false,
+ channel, channel, entry, aLoadingDocument, nullptr,
+ corsMode, nullptr);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ RefPtr<ProxyListener> pl =
+ new ProxyListener(static_cast<nsIStreamListener*>(request.get()));
+ pl.forget(listener);
+
+ // Try to add the new request into the cache.
+ PutIntoCache(originalURIKey, entry);
+
+ rv = CreateNewProxyForRequest(request, originalURI, loadGroup,
+ aLoadingDocument, aObserver, requestFlags,
+ _retval);
+
+ // Explicitly don't notify our proxy, because we're loading off the
+ // network, and necko (or things called from necko, such as
+ // imgCacheValidator) are going to call our notifications asynchronously,
+ // and we can't make it further asynchronous because observers might rely
+ // on imagelib completing its work between the channel's OnStartRequest and
+ // OnStopRequest.
+ }
+
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ (*_retval)->AddToLoadGroup();
+ return rv;
+}
+
+bool imgLoader::SupportImageWithMimeType(const nsACString& aMimeType,
+ AcceptedMimeTypes aAccept
+ /* = AcceptedMimeTypes::IMAGES */) {
+ nsAutoCString mimeType(aMimeType);
+ ToLowerCase(mimeType);
+
+ if (aAccept == AcceptedMimeTypes::IMAGES_AND_DOCUMENTS &&
+ mimeType.EqualsLiteral("image/svg+xml")) {
+ return true;
+ }
+
+ DecoderType type = DecoderFactory::GetDecoderType(mimeType.get());
+ return type != DecoderType::UNKNOWN;
+}
+
+NS_IMETHODIMP
+imgLoader::GetMIMETypeFromContent(nsIRequest* aRequest,
+ const uint8_t* aContents, uint32_t aLength,
+ nsACString& aContentType) {
+ nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
+ if (channel) {
+ nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo();
+ if (loadInfo->GetSkipContentSniffing()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ }
+
+ nsresult rv =
+ GetMimeTypeFromContent((const char*)aContents, aLength, aContentType);
+ if (NS_SUCCEEDED(rv) && channel && XRE_IsParentProcess()) {
+ if (RefPtr<mozilla::net::nsHttpChannel> httpChannel =
+ do_QueryObject(channel)) {
+ // If the image type pattern matching algorithm given bytes does not
+ // return undefined, then disable the further check and allow the
+ // response.
+ httpChannel->DisableIsOpaqueResponseAllowedAfterSniffCheck(
+ mozilla::net::nsHttpChannel::SnifferType::Image);
+ }
+ }
+
+ return rv;
+}
+
+/* static */
+nsresult imgLoader::GetMimeTypeFromContent(const char* aContents,
+ uint32_t aLength,
+ nsACString& aContentType) {
+ nsAutoCString detected;
+
+ /* Is it a GIF? */
+ if (aLength >= 6 &&
+ (!strncmp(aContents, "GIF87a", 6) || !strncmp(aContents, "GIF89a", 6))) {
+ aContentType.AssignLiteral(IMAGE_GIF);
+
+ /* or a PNG? */
+ } else if (aLength >= 8 && ((unsigned char)aContents[0] == 0x89 &&
+ (unsigned char)aContents[1] == 0x50 &&
+ (unsigned char)aContents[2] == 0x4E &&
+ (unsigned char)aContents[3] == 0x47 &&
+ (unsigned char)aContents[4] == 0x0D &&
+ (unsigned char)aContents[5] == 0x0A &&
+ (unsigned char)aContents[6] == 0x1A &&
+ (unsigned char)aContents[7] == 0x0A)) {
+ aContentType.AssignLiteral(IMAGE_PNG);
+
+ /* maybe a JPEG (JFIF)? */
+ /* JFIF files start with SOI APP0 but older files can start with SOI DQT
+ * so we test for SOI followed by any marker, i.e. FF D8 FF
+ * this will also work for SPIFF JPEG files if they appear in the future.
+ *
+ * (JFIF is 0XFF 0XD8 0XFF 0XE0 <skip 2> 0X4A 0X46 0X49 0X46 0X00)
+ */
+ } else if (aLength >= 3 && ((unsigned char)aContents[0]) == 0xFF &&
+ ((unsigned char)aContents[1]) == 0xD8 &&
+ ((unsigned char)aContents[2]) == 0xFF) {
+ aContentType.AssignLiteral(IMAGE_JPEG);
+
+ /* or how about ART? */
+ /* ART begins with JG (4A 47). Major version offset 2.
+ * Minor version offset 3. Offset 4 must be nullptr.
+ */
+ } else if (aLength >= 5 && ((unsigned char)aContents[0]) == 0x4a &&
+ ((unsigned char)aContents[1]) == 0x47 &&
+ ((unsigned char)aContents[4]) == 0x00) {
+ aContentType.AssignLiteral(IMAGE_ART);
+
+ } else if (aLength >= 2 && !strncmp(aContents, "BM", 2)) {
+ aContentType.AssignLiteral(IMAGE_BMP);
+
+ // ICOs always begin with a 2-byte 0 followed by a 2-byte 1.
+ // CURs begin with 2-byte 0 followed by 2-byte 2.
+ } else if (aLength >= 4 && (!memcmp(aContents, "\000\000\001\000", 4) ||
+ !memcmp(aContents, "\000\000\002\000", 4))) {
+ aContentType.AssignLiteral(IMAGE_ICO);
+
+ // WebPs always begin with RIFF, a 32-bit length, and WEBP.
+ } else if (aLength >= 12 && !memcmp(aContents, "RIFF", 4) &&
+ !memcmp(aContents + 8, "WEBP", 4)) {
+ aContentType.AssignLiteral(IMAGE_WEBP);
+
+ } else if (MatchesMP4(reinterpret_cast<const uint8_t*>(aContents), aLength,
+ detected) &&
+ detected.Equals(IMAGE_AVIF)) {
+ aContentType.AssignLiteral(IMAGE_AVIF);
+ } else if ((aLength >= 2 && !memcmp(aContents, "\xFF\x0A", 2)) ||
+ (aLength >= 12 &&
+ !memcmp(aContents, "\x00\x00\x00\x0CJXL \x0D\x0A\x87\x0A", 12))) {
+ // Each version is for containerless and containerful files respectively.
+ aContentType.AssignLiteral(IMAGE_JXL);
+ } else {
+ /* none of the above? I give up */
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ return NS_OK;
+}
+
+/**
+ * proxy stream listener class used to handle multipart/x-mixed-replace
+ */
+
+#include "nsIRequest.h"
+#include "nsIStreamConverterService.h"
+
+NS_IMPL_ISUPPORTS(ProxyListener, nsIStreamListener,
+ nsIThreadRetargetableStreamListener, nsIRequestObserver)
+
+ProxyListener::ProxyListener(nsIStreamListener* dest) : mDestListener(dest) {}
+
+ProxyListener::~ProxyListener() = default;
+
+/** nsIRequestObserver methods **/
+
+NS_IMETHODIMP
+ProxyListener::OnStartRequest(nsIRequest* aRequest) {
+ if (!mDestListener) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
+ if (channel) {
+ // We need to set the initiator type for the image load
+ nsCOMPtr<nsITimedChannel> timedChannel = do_QueryInterface(channel);
+ if (timedChannel) {
+ nsAutoString type;
+ timedChannel->GetInitiatorType(type);
+ if (type.IsEmpty()) {
+ timedChannel->SetInitiatorType(u"img"_ns);
+ }
+ }
+
+ nsAutoCString contentType;
+ nsresult rv = channel->GetContentType(contentType);
+
+ if (!contentType.IsEmpty()) {
+ /* If multipart/x-mixed-replace content, we'll insert a MIME decoder
+ in the pipeline to handle the content and pass it along to our
+ original listener.
+ */
+ if ("multipart/x-mixed-replace"_ns.Equals(contentType)) {
+ nsCOMPtr<nsIStreamConverterService> convServ(
+ do_GetService("@mozilla.org/streamConverters;1", &rv));
+ if (NS_SUCCEEDED(rv)) {
+ nsCOMPtr<nsIStreamListener> toListener(mDestListener);
+ nsCOMPtr<nsIStreamListener> fromListener;
+
+ rv = convServ->AsyncConvertData("multipart/x-mixed-replace", "*/*",
+ toListener, nullptr,
+ getter_AddRefs(fromListener));
+ if (NS_SUCCEEDED(rv)) {
+ mDestListener = fromListener;
+ }
+ }
+ }
+ }
+ }
+
+ return mDestListener->OnStartRequest(aRequest);
+}
+
+NS_IMETHODIMP
+ProxyListener::OnStopRequest(nsIRequest* aRequest, nsresult status) {
+ if (!mDestListener) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mDestListener->OnStopRequest(aRequest, status);
+}
+
+/** nsIStreamListener methods **/
+
+NS_IMETHODIMP
+ProxyListener::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* inStr,
+ uint64_t sourceOffset, uint32_t count) {
+ if (!mDestListener) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mDestListener->OnDataAvailable(aRequest, inStr, sourceOffset, count);
+}
+
+/** nsThreadRetargetableStreamListener methods **/
+NS_IMETHODIMP
+ProxyListener::CheckListenerChain() {
+ NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread!");
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIThreadRetargetableStreamListener> retargetableListener =
+ do_QueryInterface(mDestListener, &rv);
+ if (retargetableListener) {
+ rv = retargetableListener->CheckListenerChain();
+ }
+ MOZ_LOG(
+ gImgLog, LogLevel::Debug,
+ ("ProxyListener::CheckListenerChain %s [this=%p listener=%p rv=%" PRIx32
+ "]",
+ (NS_SUCCEEDED(rv) ? "success" : "failure"), this,
+ (nsIStreamListener*)mDestListener, static_cast<uint32_t>(rv)));
+ return rv;
+}
+
+/**
+ * http validate class. check a channel for a 304
+ */
+
+NS_IMPL_ISUPPORTS(imgCacheValidator, nsIStreamListener, nsIRequestObserver,
+ nsIThreadRetargetableStreamListener, nsIChannelEventSink,
+ nsIInterfaceRequestor, nsIAsyncVerifyRedirectCallback)
+
+imgCacheValidator::imgCacheValidator(nsProgressNotificationProxy* progress,
+ imgLoader* loader, imgRequest* request,
+ Document* aDocument,
+ uint64_t aInnerWindowId,
+ bool forcePrincipalCheckForCacheEntry)
+ : mProgressProxy(progress),
+ mRequest(request),
+ mDocument(aDocument),
+ mInnerWindowId(aInnerWindowId),
+ mImgLoader(loader),
+ mHadInsecureRedirect(false) {
+ NewRequestAndEntry(forcePrincipalCheckForCacheEntry, loader,
+ mRequest->CacheKey(), getter_AddRefs(mNewRequest),
+ getter_AddRefs(mNewEntry));
+}
+
+imgCacheValidator::~imgCacheValidator() {
+ if (mRequest) {
+ // If something went wrong, and we never unblocked the requests waiting on
+ // validation, now is our last chance. We will cancel the new request and
+ // switch the waiting proxies to it.
+ UpdateProxies(/* aCancelRequest */ true, /* aSyncNotify */ false);
+ }
+}
+
+void imgCacheValidator::AddProxy(imgRequestProxy* aProxy) {
+ // aProxy needs to be in the loadgroup since we're validating from
+ // the network.
+ aProxy->AddToLoadGroup();
+
+ mProxies.AppendElement(aProxy);
+}
+
+void imgCacheValidator::RemoveProxy(imgRequestProxy* aProxy) {
+ mProxies.RemoveElement(aProxy);
+}
+
+void imgCacheValidator::UpdateProxies(bool aCancelRequest, bool aSyncNotify) {
+ MOZ_ASSERT(mRequest);
+
+ // Clear the validator before updating the proxies. The notifications may
+ // clone an existing request, and its state could be inconsistent.
+ mRequest->SetValidator(nullptr);
+ mRequest = nullptr;
+
+ // If an error occurred, we will want to cancel the new request, and make the
+ // validating proxies point to it. Any proxies still bound to the original
+ // request which are not validating should remain untouched.
+ if (aCancelRequest) {
+ MOZ_ASSERT(mNewRequest);
+ mNewRequest->CancelAndAbort(NS_BINDING_ABORTED);
+ }
+
+ // We have finished validating the request, so we can safely take ownership
+ // of the proxy list. imgRequestProxy::SyncNotifyListener can mutate the list
+ // if imgRequestProxy::CancelAndForgetObserver is called by its owner. Note
+ // that any potential notifications should still be suppressed in
+ // imgRequestProxy::ChangeOwner because we haven't cleared the validating
+ // flag yet, and thus they will remain deferred.
+ AutoTArray<RefPtr<imgRequestProxy>, 4> proxies(std::move(mProxies));
+
+ for (auto& proxy : proxies) {
+ // First update the state of all proxies before notifying any of them
+ // to ensure a consistent state (e.g. in case the notification causes
+ // other proxies to be touched indirectly.)
+ MOZ_ASSERT(proxy->IsValidating());
+ MOZ_ASSERT(proxy->NotificationsDeferred(),
+ "Proxies waiting on cache validation should be "
+ "deferring notifications!");
+ if (mNewRequest) {
+ proxy->ChangeOwner(mNewRequest);
+ }
+ proxy->ClearValidating();
+ }
+
+ mNewRequest = nullptr;
+ mNewEntry = nullptr;
+
+ for (auto& proxy : proxies) {
+ if (aSyncNotify) {
+ // Notify synchronously, because the caller knows we are already in an
+ // asynchronously-called function (e.g. OnStartRequest).
+ proxy->SyncNotifyListener();
+ } else {
+ // Notify asynchronously, because the caller does not know our current
+ // call state (e.g. ~imgCacheValidator).
+ proxy->NotifyListener();
+ }
+ }
+}
+
+/** nsIRequestObserver methods **/
+
+NS_IMETHODIMP
+imgCacheValidator::OnStartRequest(nsIRequest* aRequest) {
+ // We may be holding on to a document, so ensure that it's released.
+ RefPtr<Document> document = mDocument.forget();
+
+ // If for some reason we don't still have an existing request (probably
+ // because OnStartRequest got delivered more than once), just bail.
+ if (!mRequest) {
+ MOZ_ASSERT_UNREACHABLE("OnStartRequest delivered more than once?");
+ aRequest->CancelWithReason(NS_BINDING_ABORTED,
+ "OnStartRequest delivered more than once?"_ns);
+ return NS_ERROR_FAILURE;
+ }
+
+ // If this request is coming from cache and has the same URI as our
+ // imgRequest, the request all our proxies are pointing at is valid, and all
+ // we have to do is tell them to notify their listeners.
+ nsCOMPtr<nsICacheInfoChannel> cacheChan(do_QueryInterface(aRequest));
+ nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
+ if (cacheChan && channel) {
+ bool isFromCache = false;
+ cacheChan->IsFromCache(&isFromCache);
+
+ nsCOMPtr<nsIURI> channelURI;
+ channel->GetURI(getter_AddRefs(channelURI));
+
+ nsCOMPtr<nsIURI> finalURI;
+ mRequest->GetFinalURI(getter_AddRefs(finalURI));
+
+ bool sameURI = false;
+ if (channelURI && finalURI) {
+ channelURI->Equals(finalURI, &sameURI);
+ }
+
+ if (isFromCache && sameURI) {
+ // We don't need to load this any more.
+ aRequest->CancelWithReason(NS_BINDING_ABORTED,
+ "imgCacheValidator::OnStartRequest"_ns);
+ mNewRequest = nullptr;
+
+ // Clear the validator before updating the proxies. The notifications may
+ // clone an existing request, and its state could be inconsistent.
+ mRequest->SetLoadId(document);
+ mRequest->SetInnerWindowID(mInnerWindowId);
+ UpdateProxies(/* aCancelRequest */ false, /* aSyncNotify */ true);
+ return NS_OK;
+ }
+ }
+
+ // We can't load out of cache. We have to create a whole new request for the
+ // data that's coming in off the channel.
+ nsCOMPtr<nsIURI> uri;
+ mRequest->GetURI(getter_AddRefs(uri));
+
+ LOG_MSG_WITH_PARAM(gImgLog,
+ "imgCacheValidator::OnStartRequest creating new request",
+ "uri", uri);
+
+ CORSMode corsmode = mRequest->GetCORSMode();
+ nsCOMPtr<nsIReferrerInfo> referrerInfo = mRequest->GetReferrerInfo();
+ nsCOMPtr<nsIPrincipal> triggeringPrincipal =
+ mRequest->GetTriggeringPrincipal();
+
+ // Doom the old request's cache entry
+ mRequest->RemoveFromCache();
+
+ // We use originalURI here to fulfil the imgIRequest contract on GetURI.
+ nsCOMPtr<nsIURI> originalURI;
+ channel->GetOriginalURI(getter_AddRefs(originalURI));
+ nsresult rv = mNewRequest->Init(originalURI, uri, mHadInsecureRedirect,
+ aRequest, channel, mNewEntry, document,
+ triggeringPrincipal, corsmode, referrerInfo);
+ if (NS_FAILED(rv)) {
+ UpdateProxies(/* aCancelRequest */ true, /* aSyncNotify */ true);
+ return rv;
+ }
+
+ mDestListener = new ProxyListener(mNewRequest);
+
+ // Try to add the new request into the cache. Note that the entry must be in
+ // the cache before the proxies' ownership changes, because adding a proxy
+ // changes the caching behaviour for imgRequests.
+ mImgLoader->PutIntoCache(mNewRequest->CacheKey(), mNewEntry);
+ UpdateProxies(/* aCancelRequest */ false, /* aSyncNotify */ true);
+ return mDestListener->OnStartRequest(aRequest);
+}
+
+NS_IMETHODIMP
+imgCacheValidator::OnStopRequest(nsIRequest* aRequest, nsresult status) {
+ // Be sure we've released the document that we may have been holding on to.
+ mDocument = nullptr;
+
+ if (!mDestListener) {
+ return NS_OK;
+ }
+
+ return mDestListener->OnStopRequest(aRequest, status);
+}
+
+/** nsIStreamListener methods **/
+
+NS_IMETHODIMP
+imgCacheValidator::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* inStr,
+ uint64_t sourceOffset, uint32_t count) {
+ if (!mDestListener) {
+ // XXX see bug 113959
+ uint32_t _retval;
+ inStr->ReadSegments(NS_DiscardSegment, nullptr, count, &_retval);
+ return NS_OK;
+ }
+
+ return mDestListener->OnDataAvailable(aRequest, inStr, sourceOffset, count);
+}
+
+/** nsIThreadRetargetableStreamListener methods **/
+
+NS_IMETHODIMP
+imgCacheValidator::CheckListenerChain() {
+ NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread!");
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIThreadRetargetableStreamListener> retargetableListener =
+ do_QueryInterface(mDestListener, &rv);
+ if (retargetableListener) {
+ rv = retargetableListener->CheckListenerChain();
+ }
+ MOZ_LOG(
+ gImgLog, LogLevel::Debug,
+ ("[this=%p] imgCacheValidator::CheckListenerChain -- rv %" PRId32 "=%s",
+ this, static_cast<uint32_t>(rv),
+ NS_SUCCEEDED(rv) ? "succeeded" : "failed"));
+ return rv;
+}
+
+/** nsIInterfaceRequestor methods **/
+
+NS_IMETHODIMP
+imgCacheValidator::GetInterface(const nsIID& aIID, void** aResult) {
+ if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
+ return QueryInterface(aIID, aResult);
+ }
+
+ return mProgressProxy->GetInterface(aIID, aResult);
+}
+
+// These functions are materially the same as the same functions in imgRequest.
+// We duplicate them because we're verifying whether cache loads are necessary,
+// not unconditionally loading.
+
+/** nsIChannelEventSink methods **/
+NS_IMETHODIMP
+imgCacheValidator::AsyncOnChannelRedirect(
+ nsIChannel* oldChannel, nsIChannel* newChannel, uint32_t flags,
+ nsIAsyncVerifyRedirectCallback* callback) {
+ // Note all cache information we get from the old channel.
+ mNewRequest->SetCacheValidation(mNewEntry, oldChannel);
+
+ // If the previous URI is a non-HTTPS URI, record that fact for later use by
+ // security code, which needs to know whether there is an insecure load at any
+ // point in the redirect chain.
+ nsCOMPtr<nsIURI> oldURI;
+ bool schemeLocal = false;
+ if (NS_FAILED(oldChannel->GetURI(getter_AddRefs(oldURI))) ||
+ NS_FAILED(NS_URIChainHasFlags(
+ oldURI, nsIProtocolHandler::URI_IS_LOCAL_RESOURCE, &schemeLocal)) ||
+ (!oldURI->SchemeIs("https") && !oldURI->SchemeIs("chrome") &&
+ !schemeLocal)) {
+ mHadInsecureRedirect = true;
+ }
+
+ // Prepare for callback
+ mRedirectCallback = callback;
+ mRedirectChannel = newChannel;
+
+ return mProgressProxy->AsyncOnChannelRedirect(oldChannel, newChannel, flags,
+ this);
+}
+
+NS_IMETHODIMP
+imgCacheValidator::OnRedirectVerifyCallback(nsresult aResult) {
+ // If we've already been told to abort, just do so.
+ if (NS_FAILED(aResult)) {
+ mRedirectCallback->OnRedirectVerifyCallback(aResult);
+ mRedirectCallback = nullptr;
+ mRedirectChannel = nullptr;
+ return NS_OK;
+ }
+
+ // make sure we have a protocol that returns data rather than opens
+ // an external application, e.g. mailto:
+ nsCOMPtr<nsIURI> uri;
+ mRedirectChannel->GetURI(getter_AddRefs(uri));
+
+ nsresult result = NS_OK;
+
+ if (nsContentUtils::IsExternalProtocol(uri)) {
+ result = NS_ERROR_ABORT;
+ }
+
+ mRedirectCallback->OnRedirectVerifyCallback(result);
+ mRedirectCallback = nullptr;
+ mRedirectChannel = nullptr;
+ return NS_OK;
+}
diff --git a/image/imgLoader.h b/image/imgLoader.h
new file mode 100644
index 0000000000..168b473333
--- /dev/null
+++ b/image/imgLoader.h
@@ -0,0 +1,534 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_imgLoader_h
+#define mozilla_image_imgLoader_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/CORSMode.h"
+#include "mozilla/Mutex.h"
+#include "mozilla/EnumSet.h"
+#include "mozilla/UniquePtr.h"
+
+#include "imgILoader.h"
+#include "imgICache.h"
+#include "nsWeakReference.h"
+#include "nsIContentSniffer.h"
+#include "nsRefPtrHashtable.h"
+#include "nsTHashSet.h"
+#include "nsExpirationTracker.h"
+#include "ImageCacheKey.h"
+#include "imgRequest.h"
+#include "nsIProgressEventSink.h"
+#include "nsIChannel.h"
+#include "nsIThreadRetargetableStreamListener.h"
+#include "imgIRequest.h"
+
+class imgLoader;
+class imgRequestProxy;
+class imgINotificationObserver;
+class nsILoadGroup;
+class imgCacheExpirationTracker;
+class imgMemoryReporter;
+
+namespace mozilla {
+namespace dom {
+class Document;
+}
+} // namespace mozilla
+
+class imgCacheEntry {
+ public:
+ imgCacheEntry(imgLoader* loader, imgRequest* request,
+ bool aForcePrincipalCheck);
+ ~imgCacheEntry();
+
+ nsrefcnt AddRef() {
+ MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
+ NS_ASSERT_OWNINGTHREAD(imgCacheEntry);
+ ++mRefCnt;
+ NS_LOG_ADDREF(this, mRefCnt, "imgCacheEntry", sizeof(*this));
+ return mRefCnt;
+ }
+
+ nsrefcnt Release() {
+ MOZ_ASSERT(0 != mRefCnt, "dup release");
+ NS_ASSERT_OWNINGTHREAD(imgCacheEntry);
+ --mRefCnt;
+ NS_LOG_RELEASE(this, mRefCnt, "imgCacheEntry");
+ if (mRefCnt == 0) {
+ mRefCnt = 1; /* stabilize */
+ delete this;
+ return 0;
+ }
+ return mRefCnt;
+ }
+
+ uint32_t GetDataSize() const { return mDataSize; }
+ void SetDataSize(uint32_t aDataSize) {
+ int32_t oldsize = mDataSize;
+ mDataSize = aDataSize;
+ UpdateCache(mDataSize - oldsize);
+ }
+
+ int32_t GetTouchedTime() const { return mTouchedTime; }
+ void SetTouchedTime(int32_t time) {
+ mTouchedTime = time;
+ Touch(/* updateTime = */ false);
+ }
+
+ uint32_t GetLoadTime() const { return mLoadTime; }
+
+ void UpdateLoadTime();
+
+ uint32_t GetExpiryTime() const { return mExpiryTime; }
+ void SetExpiryTime(uint32_t aExpiryTime) {
+ mExpiryTime = aExpiryTime;
+ Touch();
+ }
+
+ bool GetMustValidate() const { return mMustValidate; }
+ void SetMustValidate(bool aValidate) {
+ mMustValidate = aValidate;
+ Touch();
+ }
+
+ already_AddRefed<imgRequest> GetRequest() const {
+ RefPtr<imgRequest> req = mRequest;
+ return req.forget();
+ }
+
+ bool Evicted() const { return mEvicted; }
+
+ nsExpirationState* GetExpirationState() { return &mExpirationState; }
+
+ bool HasNoProxies() const { return mHasNoProxies; }
+
+ bool ForcePrincipalCheck() const { return mForcePrincipalCheck; }
+
+ bool HasNotified() const { return mHasNotified; }
+ void SetHasNotified() {
+ MOZ_ASSERT(!mHasNotified);
+ mHasNotified = true;
+ }
+
+ imgLoader* Loader() const { return mLoader; }
+
+ private: // methods
+ friend class imgLoader;
+ friend class imgCacheQueue;
+ void Touch(bool updateTime = true);
+ void UpdateCache(int32_t diff = 0);
+ void SetEvicted(bool evict) { mEvicted = evict; }
+ void SetHasNoProxies(bool hasNoProxies);
+
+ // Private, unimplemented copy constructor.
+ imgCacheEntry(const imgCacheEntry&);
+
+ private: // data
+ nsAutoRefCnt mRefCnt;
+ NS_DECL_OWNINGTHREAD
+
+ imgLoader* mLoader;
+ RefPtr<imgRequest> mRequest;
+ uint32_t mDataSize;
+ int32_t mTouchedTime;
+ uint32_t mLoadTime;
+ uint32_t mExpiryTime;
+ nsExpirationState mExpirationState;
+ bool mMustValidate : 1;
+ bool mEvicted : 1;
+ bool mHasNoProxies : 1;
+ bool mForcePrincipalCheck : 1;
+ bool mHasNotified : 1;
+};
+
+#include <vector>
+
+#define NS_IMGLOADER_CID \
+ { /* c1354898-e3fe-4602-88a7-c4520c21cb4e */ \
+ 0xc1354898, 0xe3fe, 0x4602, { \
+ 0x88, 0xa7, 0xc4, 0x52, 0x0c, 0x21, 0xcb, 0x4e \
+ } \
+ }
+
+class imgCacheQueue {
+ public:
+ imgCacheQueue();
+ void Remove(imgCacheEntry*);
+ void Push(imgCacheEntry*);
+ void MarkDirty();
+ bool IsDirty();
+ already_AddRefed<imgCacheEntry> Pop();
+ void Refresh();
+ uint32_t GetSize() const;
+ void UpdateSize(int32_t diff);
+ uint32_t GetNumElements() const;
+ bool Contains(imgCacheEntry* aEntry) const;
+ typedef nsTArray<RefPtr<imgCacheEntry>> queueContainer;
+ typedef queueContainer::iterator iterator;
+ typedef queueContainer::const_iterator const_iterator;
+
+ iterator begin();
+ const_iterator begin() const;
+ iterator end();
+ const_iterator end() const;
+
+ private:
+ queueContainer mQueue;
+ bool mDirty;
+ uint32_t mSize;
+};
+
+enum class AcceptedMimeTypes : uint8_t {
+ IMAGES,
+ IMAGES_AND_DOCUMENTS,
+};
+
+class imgLoader final : public imgILoader,
+ public nsIContentSniffer,
+ public imgICache,
+ public nsSupportsWeakReference,
+ public nsIObserver {
+ virtual ~imgLoader();
+
+ public:
+ using ImageCacheKey = mozilla::image::ImageCacheKey;
+ using imgCacheTable =
+ nsRefPtrHashtable<nsGenericHashKey<ImageCacheKey>, imgCacheEntry>;
+ using imgSet = nsTHashSet<imgRequest*>;
+ using Mutex = mozilla::Mutex;
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_IMGILOADER
+ NS_DECL_NSICONTENTSNIFFER
+ NS_DECL_IMGICACHE
+ NS_DECL_NSIOBSERVER
+
+ /**
+ * Get the normal image loader instance that is used by gecko code, creating
+ * it if necessary.
+ */
+ static imgLoader* NormalLoader();
+
+ /**
+ * Get the Private Browsing image loader instance that is used by gecko code,
+ * creating it if necessary.
+ */
+ static imgLoader* PrivateBrowsingLoader();
+
+ /**
+ * Gecko code should use NormalLoader() or PrivateBrowsingLoader() to get the
+ * appropriate image loader.
+ *
+ * This constructor is public because the XPCOM module code that creates
+ * instances of "@mozilla.org/image/loader;1" / "@mozilla.org/image/cache;1"
+ * for nsIComponentManager.createInstance()/nsIServiceManager.getService()
+ * calls (now only made by add-ons) needs access to it.
+ *
+ * XXX We would like to get rid of the nsIServiceManager.getService (and
+ * nsIComponentManager.createInstance) method of creating imgLoader objects,
+ * but there are add-ons that are still using it. These add-ons don't
+ * actually do anything useful with the loaders that they create since nobody
+ * who creates an imgLoader using this method actually QIs to imgILoader and
+ * loads images. They all just QI to imgICache and either call clearCache()
+ * or findEntryProperties(). Since they're doing this on an imgLoader that
+ * has never loaded images, these calls are useless. It seems likely that
+ * the code that is doing this is just legacy code left over from a time when
+ * there was only one imgLoader instance for the entire process. (Nowadays
+ * the correct method to get an imgILoader/imgICache is to call
+ * imgITools::getImgCacheForDocument/imgITools::getImgLoaderForDocument.)
+ * All the same, even though what these add-ons are doing is a no-op,
+ * removing the nsIServiceManager.getService method of creating/getting an
+ * imgLoader objects would cause an exception in these add-ons that could
+ * break things.
+ */
+ imgLoader();
+ nsresult Init();
+
+ bool IsImageAvailable(nsIURI*, nsIPrincipal* aTriggeringPrincipal,
+ mozilla::CORSMode, mozilla::dom::Document*);
+
+ [[nodiscard]] nsresult LoadImage(
+ nsIURI* aURI, nsIURI* aInitialDocumentURI, nsIReferrerInfo* aReferrerInfo,
+ nsIPrincipal* aLoadingPrincipal, uint64_t aRequestContextID,
+ nsILoadGroup* aLoadGroup, imgINotificationObserver* aObserver,
+ nsINode* aContext, mozilla::dom::Document* aLoadingDocument,
+ nsLoadFlags aLoadFlags, nsISupports* aCacheKey,
+ nsContentPolicyType aContentPolicyType, const nsAString& initiatorType,
+ bool aUseUrgentStartForChannel, bool aLinkPreload,
+ uint64_t aEarlyHintPreloaderId, imgRequestProxy** _retval);
+
+ [[nodiscard]] nsresult LoadImageWithChannel(
+ nsIChannel* channel, imgINotificationObserver* aObserver,
+ mozilla::dom::Document* aLoadingDocument, nsIStreamListener** listener,
+ imgRequestProxy** _retval);
+
+ static nsresult GetMimeTypeFromContent(const char* aContents,
+ uint32_t aLength,
+ nsACString& aContentType);
+
+ /**
+ * Returns true if the given mime type may be interpreted as an image.
+ *
+ * Some MIME types may be interpreted as both images and documents. (At the
+ * moment only "image/svg+xml" falls into this category, but there may be more
+ * in the future.) Callers which want this function to return true for such
+ * MIME types should pass AcceptedMimeTypes::IMAGES_AND_DOCUMENTS for
+ * @aAccept.
+ *
+ * @param aMimeType The MIME type to evaluate.
+ * @param aAcceptedMimeTypes Which kinds of MIME types to treat as images.
+ */
+ static bool SupportImageWithMimeType(
+ const nsACString&, AcceptedMimeTypes aAccept = AcceptedMimeTypes::IMAGES);
+
+ static void GlobalInit(); // for use by the factory
+ static void Shutdown(); // for use by the factory
+ static void ShutdownMemoryReporter();
+
+ enum class ClearOption {
+ ChromeOnly,
+ UnusedOnly,
+ };
+ using ClearOptions = mozilla::EnumSet<ClearOption>;
+ nsresult ClearImageCache(ClearOptions = {});
+ void MinimizeCache() { ClearImageCache({ClearOption::UnusedOnly}); }
+
+ nsresult InitCache();
+
+ bool RemoveFromCache(const ImageCacheKey& aKey);
+
+ // Enumeration describing if a given entry is in the cache queue or not.
+ // There are some cases we know the entry is definitely not in the queue.
+ enum class QueueState { MaybeExists, AlreadyRemoved };
+
+ bool RemoveFromCache(imgCacheEntry* entry,
+ QueueState aQueueState = QueueState::MaybeExists);
+
+ bool PutIntoCache(const ImageCacheKey& aKey, imgCacheEntry* aEntry);
+
+ void AddToUncachedImages(imgRequest* aRequest);
+ void RemoveFromUncachedImages(imgRequest* aRequest);
+
+ // Returns true if we should prefer evicting cache entry |two| over cache
+ // entry |one|.
+ // This mixes units in the worst way, but provides reasonable results.
+ inline static bool CompareCacheEntries(const RefPtr<imgCacheEntry>& one,
+ const RefPtr<imgCacheEntry>& two) {
+ if (!one) {
+ return false;
+ }
+ if (!two) {
+ return true;
+ }
+
+ const double sizeweight = 1.0 - sCacheTimeWeight;
+
+ // We want large, old images to be evicted first (depending on their
+ // relative weights). Since a larger time is actually newer, we subtract
+ // time's weight, so an older image has a larger weight.
+ double oneweight = double(one->GetDataSize()) * sizeweight -
+ double(one->GetTouchedTime()) * sCacheTimeWeight;
+ double twoweight = double(two->GetDataSize()) * sizeweight -
+ double(two->GetTouchedTime()) * sCacheTimeWeight;
+
+ return oneweight < twoweight;
+ }
+
+ void VerifyCacheSizes();
+
+ nsresult RemoveEntriesInternal(nsIPrincipal* aPrincipal,
+ const nsACString* aBaseDomain);
+
+ // The image loader maintains a hash table of all imgCacheEntries. However,
+ // only some of them will be evicted from the cache: those who have no
+ // imgRequestProxies watching their imgRequests.
+ //
+ // Once an imgRequest has no imgRequestProxies, it should notify us by
+ // calling HasNoObservers(), and null out its cache entry pointer.
+ //
+ // Upon having a proxy start observing again, it should notify us by calling
+ // HasObservers(). The request's cache entry will be re-set before this
+ // happens, by calling imgRequest::SetCacheEntry() when an entry with no
+ // observers is re-requested.
+ bool SetHasNoProxies(imgRequest* aRequest, imgCacheEntry* aEntry);
+ bool SetHasProxies(imgRequest* aRequest);
+
+ private: // methods
+ static already_AddRefed<imgLoader> CreateImageLoader();
+
+ bool ValidateEntry(imgCacheEntry* aEntry, nsIURI* aURI,
+ nsIURI* aInitialDocumentURI,
+ nsIReferrerInfo* aReferrerInfo, nsILoadGroup* aLoadGroup,
+ imgINotificationObserver* aObserver,
+ mozilla::dom::Document* aLoadingDocument,
+ nsLoadFlags aLoadFlags,
+ nsContentPolicyType aLoadPolicyType,
+ bool aCanMakeNewChannel, bool* aNewChannelCreated,
+ imgRequestProxy** aProxyRequest,
+ nsIPrincipal* aTriggeringPrincipal, mozilla::CORSMode,
+ bool aLinkPreload, uint64_t aEarlyHintPreloaderId);
+
+ bool ValidateRequestWithNewChannel(
+ imgRequest* request, nsIURI* aURI, nsIURI* aInitialDocumentURI,
+ nsIReferrerInfo* aReferrerInfo, nsILoadGroup* aLoadGroup,
+ imgINotificationObserver* aObserver,
+ mozilla::dom::Document* aLoadingDocument, uint64_t aInnerWindowId,
+ nsLoadFlags aLoadFlags, nsContentPolicyType aContentPolicyType,
+ imgRequestProxy** aProxyRequest, nsIPrincipal* aLoadingPrincipal,
+ mozilla::CORSMode, bool aLinkPreload, uint64_t aEarlyHintPreloaderId,
+ bool* aNewChannelCreated);
+
+ void NotifyObserversForCachedImage(imgCacheEntry* aEntry, imgRequest* request,
+ nsIURI* aURI,
+ nsIReferrerInfo* aReferrerInfo,
+ mozilla::dom::Document* aLoadingDocument,
+ nsIPrincipal* aLoadingPrincipal,
+ mozilla::CORSMode,
+ uint64_t aEarlyHintPreloaderId);
+ // aURI may be different from imgRequest's URI in the case of blob URIs, as we
+ // can share requests with different URIs.
+ nsresult CreateNewProxyForRequest(imgRequest* aRequest, nsIURI* aURI,
+ nsILoadGroup* aLoadGroup,
+ mozilla::dom::Document* aLoadingDocument,
+ imgINotificationObserver* aObserver,
+ nsLoadFlags aLoadFlags,
+ imgRequestProxy** _retval);
+
+ nsresult EvictEntries(bool aChromeOnly);
+
+ void CacheEntriesChanged(int32_t aSizeDiff);
+ void CheckCacheLimits();
+
+ private: // data
+ friend class imgCacheEntry;
+ friend class imgMemoryReporter;
+
+ imgCacheTable mCache;
+ imgCacheQueue mCacheQueue;
+
+ // Hash set of every imgRequest for this loader that isn't in mCache or
+ // mChromeCache. The union over all imgLoader's of mCache, mChromeCache, and
+ // mUncachedImages should be every imgRequest that is alive. These are weak
+ // pointers so we rely on the imgRequest destructor to remove itself.
+ imgSet mUncachedImages MOZ_GUARDED_BY(mUncachedImagesMutex);
+ // The imgRequest can have refs to them held on non-main thread, so we need
+ // a mutex because we modify the uncached images set from the imgRequest
+ // destructor.
+ Mutex mUncachedImagesMutex;
+
+ static double sCacheTimeWeight;
+ static uint32_t sCacheMaxSize;
+ static imgMemoryReporter* sMemReporter;
+
+ mozilla::UniquePtr<imgCacheExpirationTracker> mCacheTracker;
+ bool mRespectPrivacy;
+};
+
+/**
+ * proxy stream listener class used to handle multipart/x-mixed-replace
+ */
+
+#include "nsCOMPtr.h"
+#include "nsIStreamListener.h"
+#include "nsIThreadRetargetableStreamListener.h"
+
+class ProxyListener : public nsIStreamListener,
+ public nsIThreadRetargetableStreamListener {
+ public:
+ explicit ProxyListener(nsIStreamListener* dest);
+
+ /* additional members */
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSISTREAMLISTENER
+ NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
+ NS_DECL_NSIREQUESTOBSERVER
+
+ private:
+ virtual ~ProxyListener();
+
+ nsCOMPtr<nsIStreamListener> mDestListener;
+};
+
+/**
+ * A class that implements nsIProgressEventSink and forwards all calls to it to
+ * the original notification callbacks of the channel. Also implements
+ * nsIInterfaceRequestor and gives out itself for nsIProgressEventSink calls,
+ * and forwards everything else to the channel's notification callbacks.
+ */
+class nsProgressNotificationProxy final : public nsIProgressEventSink,
+ public nsIChannelEventSink,
+ public nsIInterfaceRequestor {
+ public:
+ nsProgressNotificationProxy(nsIChannel* channel, imgIRequest* proxy)
+ : mImageRequest(proxy) {
+ channel->GetNotificationCallbacks(getter_AddRefs(mOriginalCallbacks));
+ }
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPROGRESSEVENTSINK
+ NS_DECL_NSICHANNELEVENTSINK
+ NS_DECL_NSIINTERFACEREQUESTOR
+ private:
+ ~nsProgressNotificationProxy() = default;
+
+ nsCOMPtr<nsIInterfaceRequestor> mOriginalCallbacks;
+ nsCOMPtr<nsIRequest> mImageRequest;
+};
+
+/**
+ * validate checker
+ */
+
+#include "nsCOMArray.h"
+
+class imgCacheValidator : public nsIStreamListener,
+ public nsIThreadRetargetableStreamListener,
+ public nsIChannelEventSink,
+ public nsIInterfaceRequestor,
+ public nsIAsyncVerifyRedirectCallback {
+ public:
+ imgCacheValidator(nsProgressNotificationProxy* progress, imgLoader* loader,
+ imgRequest* aRequest, mozilla::dom::Document* aDocument,
+ uint64_t aInnerWindowId,
+ bool forcePrincipalCheckForCacheEntry);
+
+ void AddProxy(imgRequestProxy* aProxy);
+ void RemoveProxy(imgRequestProxy* aProxy);
+
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
+ NS_DECL_NSISTREAMLISTENER
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSICHANNELEVENTSINK
+ NS_DECL_NSIINTERFACEREQUESTOR
+ NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
+
+ private:
+ void UpdateProxies(bool aCancelRequest, bool aSyncNotify);
+ virtual ~imgCacheValidator();
+
+ nsCOMPtr<nsIStreamListener> mDestListener;
+ RefPtr<nsProgressNotificationProxy> mProgressProxy;
+ nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
+ nsCOMPtr<nsIChannel> mRedirectChannel;
+
+ RefPtr<imgRequest> mRequest;
+ AutoTArray<RefPtr<imgRequestProxy>, 4> mProxies;
+
+ RefPtr<imgRequest> mNewRequest;
+ RefPtr<imgCacheEntry> mNewEntry;
+
+ RefPtr<mozilla::dom::Document> mDocument;
+ uint64_t mInnerWindowId;
+
+ imgLoader* mImgLoader;
+
+ bool mHadInsecureRedirect;
+};
+
+#endif // mozilla_image_imgLoader_h
diff --git a/image/imgRequest.cpp b/image/imgRequest.cpp
new file mode 100644
index 0000000000..9eaefa58d1
--- /dev/null
+++ b/image/imgRequest.cpp
@@ -0,0 +1,1231 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "imgRequest.h"
+#include "ImageLogging.h"
+
+#include "imgLoader.h"
+#include "imgRequestProxy.h"
+#include "DecodePool.h"
+#include "ProgressTracker.h"
+#include "ImageFactory.h"
+#include "Image.h"
+#include "MultipartImage.h"
+#include "RasterImage.h"
+
+#include "nsIChannel.h"
+#include "nsICacheInfoChannel.h"
+#include "nsIClassOfService.h"
+#include "mozilla/dom/Document.h"
+#include "nsIThreadRetargetableRequest.h"
+#include "nsIInputStream.h"
+#include "nsIMultiPartChannel.h"
+#include "nsIHttpChannel.h"
+#include "nsMimeTypes.h"
+
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsISupportsPrimitives.h"
+#include "nsIScriptSecurityManager.h"
+#include "nsComponentManagerUtils.h"
+#include "nsContentUtils.h"
+#include "nsEscape.h"
+
+#include "prtime.h" // for PR_Now
+#include "nsNetUtil.h"
+#include "nsIProtocolHandler.h"
+#include "imgIRequest.h"
+#include "nsProperties.h"
+#include "nsIURL.h"
+
+#include "mozilla/IntegerPrintfMacros.h"
+#include "mozilla/SizeOfState.h"
+
+using namespace mozilla;
+using namespace mozilla::image;
+
+#define LOG_TEST(level) (MOZ_LOG_TEST(gImgLog, (level)))
+
+NS_IMPL_ISUPPORTS(imgRequest, nsIStreamListener, nsIRequestObserver,
+ nsIThreadRetargetableStreamListener, nsIChannelEventSink,
+ nsIInterfaceRequestor, nsIAsyncVerifyRedirectCallback)
+
+imgRequest::imgRequest(imgLoader* aLoader, const ImageCacheKey& aCacheKey)
+ : mLoader(aLoader),
+ mCacheKey(aCacheKey),
+ mLoadId(nullptr),
+ mFirstProxy(nullptr),
+ mValidator(nullptr),
+ mCORSMode(CORS_NONE),
+ mImageErrorCode(NS_OK),
+ mImageAvailable(false),
+ mIsDeniedCrossSiteCORSRequest(false),
+ mIsCrossSiteNoCORSRequest(false),
+ mMutex("imgRequest"),
+ mProgressTracker(new ProgressTracker()),
+ mIsMultiPartChannel(false),
+ mIsInCache(false),
+ mDecodeRequested(false),
+ mNewPartPending(false),
+ mHadInsecureRedirect(false),
+ mInnerWindowId(0) {
+ LOG_FUNC(gImgLog, "imgRequest::imgRequest()");
+}
+
+imgRequest::~imgRequest() {
+ if (mLoader) {
+ mLoader->RemoveFromUncachedImages(this);
+ }
+ if (mURI) {
+ LOG_FUNC_WITH_PARAM(gImgLog, "imgRequest::~imgRequest()", "keyuri", mURI);
+ } else
+ LOG_FUNC(gImgLog, "imgRequest::~imgRequest()");
+}
+
+nsresult imgRequest::Init(
+ nsIURI* aURI, nsIURI* aFinalURI, bool aHadInsecureRedirect,
+ nsIRequest* aRequest, nsIChannel* aChannel, imgCacheEntry* aCacheEntry,
+ mozilla::dom::Document* aLoadingDocument,
+ nsIPrincipal* aTriggeringPrincipal, mozilla::CORSMode aCORSMode,
+ nsIReferrerInfo* aReferrerInfo) MOZ_NO_THREAD_SAFETY_ANALYSIS {
+ MOZ_ASSERT(NS_IsMainThread(), "Cannot use nsIURI off main thread!");
+ // Init() can only be called once, and that's before it can be used off
+ // mainthread
+
+ LOG_FUNC(gImgLog, "imgRequest::Init");
+
+ MOZ_ASSERT(!mImage, "Multiple calls to init");
+ MOZ_ASSERT(aURI, "No uri");
+ MOZ_ASSERT(aFinalURI, "No final uri");
+ MOZ_ASSERT(aRequest, "No request");
+ MOZ_ASSERT(aChannel, "No channel");
+
+ mProperties = new nsProperties();
+ mURI = aURI;
+ mFinalURI = aFinalURI;
+ mRequest = aRequest;
+ mChannel = aChannel;
+ mTimedChannel = do_QueryInterface(mChannel);
+ mTriggeringPrincipal = aTriggeringPrincipal;
+ mCORSMode = aCORSMode;
+ mReferrerInfo = aReferrerInfo;
+
+ // If the original URI and the final URI are different, check whether the
+ // original URI is secure. We deliberately don't take the final URI into
+ // account, as it needs to be handled using more complicated rules than
+ // earlier elements of the redirect chain.
+ if (aURI != aFinalURI) {
+ bool schemeLocal = false;
+ if (NS_FAILED(NS_URIChainHasFlags(
+ aURI, nsIProtocolHandler::URI_IS_LOCAL_RESOURCE, &schemeLocal)) ||
+ (!aURI->SchemeIs("https") && !aURI->SchemeIs("chrome") &&
+ !schemeLocal)) {
+ mHadInsecureRedirect = true;
+ }
+ }
+
+ // imgCacheValidator may have handled redirects before we were created, so we
+ // allow the caller to let us know if any redirects were insecure.
+ mHadInsecureRedirect = mHadInsecureRedirect || aHadInsecureRedirect;
+
+ mChannel->GetNotificationCallbacks(getter_AddRefs(mPrevChannelSink));
+
+ NS_ASSERTION(mPrevChannelSink != this,
+ "Initializing with a channel that already calls back to us!");
+
+ mChannel->SetNotificationCallbacks(this);
+
+ mCacheEntry = aCacheEntry;
+ mCacheEntry->UpdateLoadTime();
+
+ SetLoadId(aLoadingDocument);
+
+ // Grab the inner window ID of the loading document, if possible.
+ if (aLoadingDocument) {
+ mInnerWindowId = aLoadingDocument->InnerWindowID();
+ }
+
+ return NS_OK;
+}
+
+bool imgRequest::CanReuseWithoutValidation(dom::Document* aDoc) const {
+ // If the request's loadId is the same as the aLoadingDocument, then it is ok
+ // to use this one because it has already been validated for this context.
+ // XXX: nullptr seems to be a 'special' key value that indicates that NO
+ // validation is required.
+ // XXX: we also check the window ID because the loadID() can return a reused
+ // pointer of a document. This can still happen for non-document image
+ // cache entries.
+ void* key = (void*)aDoc;
+ uint64_t innerWindowID = aDoc ? aDoc->InnerWindowID() : 0;
+ if (LoadId() == key && InnerWindowID() == innerWindowID) {
+ return true;
+ }
+
+ // As a special-case, if this is a print preview document, also validate on
+ // the original document. This allows to print uncacheable images.
+ if (dom::Document* original = aDoc ? aDoc->GetOriginalDocument() : nullptr) {
+ return CanReuseWithoutValidation(original);
+ }
+
+ return false;
+}
+
+void imgRequest::ClearLoader() { mLoader = nullptr; }
+
+already_AddRefed<nsIPrincipal> imgRequest::GetTriggeringPrincipal() const {
+ nsCOMPtr<nsIPrincipal> principal = mTriggeringPrincipal;
+ return principal.forget();
+}
+
+already_AddRefed<ProgressTracker> imgRequest::GetProgressTracker() const {
+ MutexAutoLock lock(mMutex);
+
+ if (mImage) {
+ MOZ_ASSERT(!mProgressTracker,
+ "Should have given mProgressTracker to mImage");
+ return mImage->GetProgressTracker();
+ }
+ MOZ_ASSERT(mProgressTracker,
+ "Should have mProgressTracker until we create mImage");
+ RefPtr<ProgressTracker> progressTracker = mProgressTracker;
+ MOZ_ASSERT(progressTracker);
+ return progressTracker.forget();
+}
+
+void imgRequest::SetCacheEntry(imgCacheEntry* entry) { mCacheEntry = entry; }
+
+bool imgRequest::HasCacheEntry() const { return mCacheEntry != nullptr; }
+
+void imgRequest::ResetCacheEntry() {
+ if (HasCacheEntry()) {
+ mCacheEntry->SetDataSize(0);
+ }
+}
+
+void imgRequest::AddProxy(imgRequestProxy* proxy) {
+ MOZ_ASSERT(proxy, "null imgRequestProxy passed in");
+ LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::AddProxy", "proxy", proxy);
+
+ if (!mFirstProxy) {
+ // Save a raw pointer to the first proxy we see, for use in the network
+ // priority logic.
+ mFirstProxy = proxy;
+ }
+
+ // If we're empty before adding, we have to tell the loader we now have
+ // proxies.
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ if (progressTracker->ObserverCount() == 0) {
+ MOZ_ASSERT(mURI, "Trying to SetHasProxies without key uri.");
+ if (mLoader) {
+ mLoader->SetHasProxies(this);
+ }
+ }
+
+ progressTracker->AddObserver(proxy);
+}
+
+nsresult imgRequest::RemoveProxy(imgRequestProxy* proxy, nsresult aStatus) {
+ LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::RemoveProxy", "proxy", proxy);
+
+ // This will remove our animation consumers, so after removing
+ // this proxy, we don't end up without proxies with observers, but still
+ // have animation consumers.
+ proxy->ClearAnimationConsumers();
+
+ // Let the status tracker do its thing before we potentially call Cancel()
+ // below, because Cancel() may result in OnStopRequest being called back
+ // before Cancel() returns, leaving the image in a different state then the
+ // one it was in at this point.
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ if (!progressTracker->RemoveObserver(proxy)) {
+ return NS_OK;
+ }
+
+ if (progressTracker->ObserverCount() == 0) {
+ // If we have no observers, there's nothing holding us alive. If we haven't
+ // been cancelled and thus removed from the cache, tell the image loader so
+ // we can be evicted from the cache.
+ if (mCacheEntry) {
+ MOZ_ASSERT(mURI, "Removing last observer without key uri.");
+
+ if (mLoader) {
+ mLoader->SetHasNoProxies(this, mCacheEntry);
+ }
+ } else {
+ LOG_MSG_WITH_PARAM(gImgLog, "imgRequest::RemoveProxy no cache entry",
+ "uri", mURI);
+ }
+
+ /* If |aStatus| is a failure code, then cancel the load if it is still in
+ progress. Otherwise, let the load continue, keeping 'this' in the cache
+ with no observers. This way, if a proxy is destroyed without calling
+ cancel on it, it won't leak and won't leave a bad pointer in the observer
+ list.
+ */
+ if (!(progressTracker->GetProgress() & FLAG_LAST_PART_COMPLETE) &&
+ NS_FAILED(aStatus)) {
+ LOG_MSG(gImgLog, "imgRequest::RemoveProxy",
+ "load in progress. canceling");
+
+ this->Cancel(NS_BINDING_ABORTED);
+ }
+
+ /* break the cycle from the cache entry. */
+ mCacheEntry = nullptr;
+ }
+
+ return NS_OK;
+}
+
+uint64_t imgRequest::InnerWindowID() const {
+ MutexAutoLock lock(mMutex);
+ return mInnerWindowId;
+}
+
+void imgRequest::SetInnerWindowID(uint64_t aInnerWindowId) {
+ MutexAutoLock lock(mMutex);
+ mInnerWindowId = aInnerWindowId;
+}
+
+void imgRequest::CancelAndAbort(nsresult aStatus) {
+ LOG_SCOPE(gImgLog, "imgRequest::CancelAndAbort");
+
+ Cancel(aStatus);
+
+ // It's possible for the channel to fail to open after we've set our
+ // notification callbacks. In that case, make sure to break the cycle between
+ // the channel and us, because it won't.
+ if (mChannel) {
+ mChannel->SetNotificationCallbacks(mPrevChannelSink);
+ mPrevChannelSink = nullptr;
+ }
+}
+
+class imgRequestMainThreadCancel : public Runnable {
+ public:
+ imgRequestMainThreadCancel(imgRequest* aImgRequest, nsresult aStatus)
+ : Runnable("imgRequestMainThreadCancel"),
+ mImgRequest(aImgRequest),
+ mStatus(aStatus) {
+ MOZ_ASSERT(!NS_IsMainThread(), "Create me off main thread only!");
+ MOZ_ASSERT(aImgRequest);
+ }
+
+ NS_IMETHOD Run() override {
+ MOZ_ASSERT(NS_IsMainThread(), "I should be running on the main thread!");
+ mImgRequest->ContinueCancel(mStatus);
+ return NS_OK;
+ }
+
+ private:
+ RefPtr<imgRequest> mImgRequest;
+ nsresult mStatus;
+};
+
+void imgRequest::Cancel(nsresult aStatus) {
+ /* The Cancel() method here should only be called by this class. */
+ LOG_SCOPE(gImgLog, "imgRequest::Cancel");
+
+ if (NS_IsMainThread()) {
+ ContinueCancel(aStatus);
+ } else {
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ nsCOMPtr<nsIEventTarget> eventTarget = progressTracker->GetEventTarget();
+ nsCOMPtr<nsIRunnable> ev = new imgRequestMainThreadCancel(this, aStatus);
+ eventTarget->Dispatch(ev.forget(), NS_DISPATCH_NORMAL);
+ }
+}
+
+void imgRequest::ContinueCancel(nsresult aStatus) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ progressTracker->SyncNotifyProgress(FLAG_HAS_ERROR);
+
+ RemoveFromCache();
+
+ if (mRequest && !(progressTracker->GetProgress() & FLAG_LAST_PART_COMPLETE)) {
+ mRequest->CancelWithReason(aStatus, "imgRequest::ContinueCancel"_ns);
+ }
+}
+
+class imgRequestMainThreadEvict : public Runnable {
+ public:
+ explicit imgRequestMainThreadEvict(imgRequest* aImgRequest)
+ : Runnable("imgRequestMainThreadEvict"), mImgRequest(aImgRequest) {
+ MOZ_ASSERT(!NS_IsMainThread(), "Create me off main thread only!");
+ MOZ_ASSERT(aImgRequest);
+ }
+
+ NS_IMETHOD Run() override {
+ MOZ_ASSERT(NS_IsMainThread(), "I should be running on the main thread!");
+ mImgRequest->ContinueEvict();
+ return NS_OK;
+ }
+
+ private:
+ RefPtr<imgRequest> mImgRequest;
+};
+
+// EvictFromCache() is written to allowed to get called from any thread
+void imgRequest::EvictFromCache() {
+ /* The EvictFromCache() method here should only be called by this class. */
+ LOG_SCOPE(gImgLog, "imgRequest::EvictFromCache");
+
+ if (NS_IsMainThread()) {
+ ContinueEvict();
+ } else {
+ NS_DispatchToMainThread(new imgRequestMainThreadEvict(this));
+ }
+}
+
+// Helper-method used by EvictFromCache()
+void imgRequest::ContinueEvict() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ RemoveFromCache();
+}
+
+void imgRequest::StartDecoding() {
+ MutexAutoLock lock(mMutex);
+ mDecodeRequested = true;
+}
+
+bool imgRequest::IsDecodeRequested() const {
+ MutexAutoLock lock(mMutex);
+ return mDecodeRequested;
+}
+
+nsresult imgRequest::GetURI(nsIURI** aURI) {
+ MOZ_ASSERT(aURI);
+
+ LOG_FUNC(gImgLog, "imgRequest::GetURI");
+
+ if (mURI) {
+ *aURI = mURI;
+ NS_ADDREF(*aURI);
+ return NS_OK;
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+nsresult imgRequest::GetFinalURI(nsIURI** aURI) {
+ MOZ_ASSERT(aURI);
+
+ LOG_FUNC(gImgLog, "imgRequest::GetFinalURI");
+
+ if (mFinalURI) {
+ *aURI = mFinalURI;
+ NS_ADDREF(*aURI);
+ return NS_OK;
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+bool imgRequest::IsChrome() const { return mURI->SchemeIs("chrome"); }
+
+bool imgRequest::IsData() const { return mURI->SchemeIs("data"); }
+
+nsresult imgRequest::GetImageErrorCode() { return mImageErrorCode; }
+
+void imgRequest::RemoveFromCache() {
+ LOG_SCOPE(gImgLog, "imgRequest::RemoveFromCache");
+
+ bool isInCache = false;
+
+ {
+ MutexAutoLock lock(mMutex);
+ isInCache = mIsInCache;
+ }
+
+ if (isInCache && mLoader) {
+ // mCacheEntry is nulled out when we have no more observers.
+ if (mCacheEntry) {
+ mLoader->RemoveFromCache(mCacheEntry);
+ } else {
+ mLoader->RemoveFromCache(mCacheKey);
+ }
+ }
+
+ mCacheEntry = nullptr;
+}
+
+bool imgRequest::HasConsumers() const {
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ return progressTracker && progressTracker->ObserverCount() > 0;
+}
+
+already_AddRefed<image::Image> imgRequest::GetImage() const {
+ MutexAutoLock lock(mMutex);
+ RefPtr<image::Image> image = mImage;
+ return image.forget();
+}
+
+void imgRequest::GetFileName(nsACString& aFileName) {
+ nsAutoString fileName;
+
+ nsCOMPtr<nsISupportsCString> supportscstr;
+ if (NS_SUCCEEDED(mProperties->Get("content-disposition",
+ NS_GET_IID(nsISupportsCString),
+ getter_AddRefs(supportscstr))) &&
+ supportscstr) {
+ nsAutoCString cdHeader;
+ supportscstr->GetData(cdHeader);
+ NS_GetFilenameFromDisposition(fileName, cdHeader);
+ }
+
+ if (fileName.IsEmpty()) {
+ nsCOMPtr<nsIURL> imgUrl(do_QueryInterface(mURI));
+ if (imgUrl) {
+ imgUrl->GetFileName(aFileName);
+ NS_UnescapeURL(aFileName);
+ }
+ } else {
+ aFileName = NS_ConvertUTF16toUTF8(fileName);
+ }
+}
+
+int32_t imgRequest::Priority() const {
+ int32_t priority = nsISupportsPriority::PRIORITY_NORMAL;
+ nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mRequest);
+ if (p) {
+ p->GetPriority(&priority);
+ }
+ return priority;
+}
+
+void imgRequest::AdjustPriority(imgRequestProxy* proxy, int32_t delta) {
+ // only the first proxy is allowed to modify the priority of this image load.
+ //
+ // XXX(darin): this is probably not the most optimal algorithm as we may want
+ // to increase the priority of requests that have a lot of proxies. the key
+ // concern though is that image loads remain lower priority than other pieces
+ // of content such as link clicks, CSS, and JS.
+ //
+ if (!mFirstProxy || proxy != mFirstProxy) {
+ return;
+ }
+
+ AdjustPriorityInternal(delta);
+}
+
+void imgRequest::AdjustPriorityInternal(int32_t aDelta) {
+ nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mChannel);
+ if (p) {
+ p->AdjustPriority(aDelta);
+ }
+}
+
+void imgRequest::BoostPriority(uint32_t aCategory) {
+ if (!StaticPrefs::image_layout_network_priority()) {
+ return;
+ }
+
+ uint32_t newRequestedCategory =
+ (mBoostCategoriesRequested & aCategory) ^ aCategory;
+ if (!newRequestedCategory) {
+ // priority boost for each category can only apply once.
+ return;
+ }
+
+ MOZ_LOG(gImgLog, LogLevel::Debug,
+ ("[this=%p] imgRequest::BoostPriority for category %x", this,
+ newRequestedCategory));
+
+ int32_t delta = 0;
+
+ if (newRequestedCategory & imgIRequest::CATEGORY_FRAME_INIT) {
+ --delta;
+ }
+
+ if (newRequestedCategory & imgIRequest::CATEGORY_FRAME_STYLE) {
+ --delta;
+ }
+
+ if (newRequestedCategory & imgIRequest::CATEGORY_SIZE_QUERY) {
+ --delta;
+ }
+
+ if (newRequestedCategory & imgIRequest::CATEGORY_DISPLAY) {
+ delta += nsISupportsPriority::PRIORITY_HIGH;
+ }
+
+ AdjustPriorityInternal(delta);
+ mBoostCategoriesRequested |= newRequestedCategory;
+}
+
+void imgRequest::SetIsInCache(bool aInCache) {
+ LOG_FUNC_WITH_PARAM(gImgLog, "imgRequest::SetIsCacheable", "aInCache",
+ aInCache);
+ MutexAutoLock lock(mMutex);
+ mIsInCache = aInCache;
+}
+
+void imgRequest::UpdateCacheEntrySize() {
+ if (!mCacheEntry) {
+ return;
+ }
+
+ RefPtr<Image> image = GetImage();
+ SizeOfState state(moz_malloc_size_of);
+ size_t size = image->SizeOfSourceWithComputedFallback(state);
+ mCacheEntry->SetDataSize(size);
+}
+
+void imgRequest::SetCacheValidation(imgCacheEntry* aCacheEntry,
+ nsIRequest* aRequest) {
+ /* get the expires info */
+ if (!aCacheEntry || aCacheEntry->GetExpiryTime() != 0) {
+ return;
+ }
+
+ RefPtr<imgRequest> req = aCacheEntry->GetRequest();
+ MOZ_ASSERT(req);
+ RefPtr<nsIURI> uri;
+ req->GetURI(getter_AddRefs(uri));
+ // TODO(emilio): Seems we should be able to assert `uri` is not null, but we
+ // get here in such cases sometimes (like for some redirects, see
+ // docshell/test/chrome/test_bug89419.xhtml).
+ //
+ // We have the original URI in the cache key though, probably we should be
+ // using that instead of relying on Init() getting called.
+ auto info = nsContentUtils::GetSubresourceCacheValidationInfo(aRequest, uri);
+
+ // Expiration time defaults to 0. We set the expiration time on our entry if
+ // it hasn't been set yet.
+ if (!info.mExpirationTime) {
+ // If the channel doesn't support caching, then ensure this expires the
+ // next time it is used.
+ info.mExpirationTime.emplace(nsContentUtils::SecondsFromPRTime(PR_Now()) -
+ 1);
+ }
+ aCacheEntry->SetExpiryTime(*info.mExpirationTime);
+ // Cache entries default to not needing to validate. We ensure that
+ // multiple calls to this function don't override an earlier decision to
+ // validate by making validation a one-way decision.
+ if (info.mMustRevalidate) {
+ aCacheEntry->SetMustValidate(info.mMustRevalidate);
+ }
+}
+
+bool imgRequest::GetMultipart() const {
+ MutexAutoLock lock(mMutex);
+ return mIsMultiPartChannel;
+}
+
+bool imgRequest::HadInsecureRedirect() const {
+ MutexAutoLock lock(mMutex);
+ return mHadInsecureRedirect;
+}
+
+/** nsIRequestObserver methods **/
+
+NS_IMETHODIMP
+imgRequest::OnStartRequest(nsIRequest* aRequest) {
+ LOG_SCOPE(gImgLog, "imgRequest::OnStartRequest");
+
+ RefPtr<Image> image;
+
+ if (nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest)) {
+ nsresult rv;
+ nsCOMPtr<nsILoadInfo> loadInfo = httpChannel->LoadInfo();
+ mIsDeniedCrossSiteCORSRequest =
+ loadInfo->GetTainting() == LoadTainting::CORS &&
+ (NS_FAILED(httpChannel->GetStatus(&rv)) || NS_FAILED(rv));
+ mIsCrossSiteNoCORSRequest = loadInfo->GetTainting() == LoadTainting::Opaque;
+ }
+
+ // Figure out if we're multipart.
+ nsCOMPtr<nsIMultiPartChannel> multiPartChannel = do_QueryInterface(aRequest);
+ {
+ MutexAutoLock lock(mMutex);
+
+ MOZ_ASSERT(multiPartChannel || !mIsMultiPartChannel,
+ "Stopped being multipart?");
+
+ mNewPartPending = true;
+ image = mImage;
+ mIsMultiPartChannel = bool(multiPartChannel);
+ }
+
+ // If we're not multipart, we shouldn't have an image yet.
+ if (image && !multiPartChannel) {
+ MOZ_ASSERT_UNREACHABLE("Already have an image for a non-multipart request");
+ Cancel(NS_IMAGELIB_ERROR_FAILURE);
+ return NS_ERROR_FAILURE;
+ }
+
+ /*
+ * If mRequest is null here, then we need to set it so that we'll be able to
+ * cancel it if our Cancel() method is called. Note that this can only
+ * happen for multipart channels. We could simply not null out mRequest for
+ * non-last parts, if GetIsLastPart() were reliable, but it's not. See
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=339610
+ */
+ if (!mRequest) {
+ MOZ_ASSERT(multiPartChannel, "Should have mRequest unless we're multipart");
+ nsCOMPtr<nsIChannel> baseChannel;
+ multiPartChannel->GetBaseChannel(getter_AddRefs(baseChannel));
+ mRequest = baseChannel;
+ }
+
+ nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
+ if (channel) {
+ /* Get our principal */
+ nsCOMPtr<nsIScriptSecurityManager> secMan =
+ nsContentUtils::GetSecurityManager();
+ if (secMan) {
+ nsresult rv = secMan->GetChannelResultPrincipal(
+ channel, getter_AddRefs(mPrincipal));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ }
+ }
+
+ SetCacheValidation(mCacheEntry, aRequest);
+
+ // Shouldn't we be dead already if this gets hit?
+ // Probably multipart/x-mixed-replace...
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ if (progressTracker->ObserverCount() == 0) {
+ this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
+ }
+
+ // Try to retarget OnDataAvailable to a decode thread. We must process data
+ // URIs synchronously as per the spec however.
+ if (!channel || IsData()) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIThreadRetargetableRequest> retargetable =
+ do_QueryInterface(aRequest);
+ if (retargetable) {
+ nsAutoCString mimeType;
+ nsresult rv = channel->GetContentType(mimeType);
+ if (NS_SUCCEEDED(rv) && !mimeType.EqualsLiteral(IMAGE_SVG_XML)) {
+ // Retarget OnDataAvailable to the DecodePool's IO thread.
+ nsCOMPtr<nsISerialEventTarget> target =
+ DecodePool::Singleton()->GetIOEventTarget();
+ rv = retargetable->RetargetDeliveryTo(target);
+ }
+ MOZ_LOG(gImgLog, LogLevel::Warning,
+ ("[this=%p] imgRequest::OnStartRequest -- "
+ "RetargetDeliveryTo rv %" PRIu32 "=%s\n",
+ this, static_cast<uint32_t>(rv),
+ NS_SUCCEEDED(rv) ? "succeeded" : "failed"));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequest::OnStopRequest(nsIRequest* aRequest, nsresult status) {
+ LOG_FUNC(gImgLog, "imgRequest::OnStopRequest");
+ MOZ_ASSERT(NS_IsMainThread(), "Can't send notifications off-main-thread");
+
+ RefPtr<Image> image = GetImage();
+
+ RefPtr<imgRequest> strongThis = this;
+
+ bool isMultipart = false;
+ bool newPartPending = false;
+ {
+ MutexAutoLock lock(mMutex);
+ isMultipart = mIsMultiPartChannel;
+ newPartPending = mNewPartPending;
+ }
+ if (isMultipart && newPartPending) {
+ OnDataAvailable(aRequest, nullptr, 0, 0);
+ }
+
+ // XXXldb What if this is a non-last part of a multipart request?
+ // xxx before we release our reference to mRequest, lets
+ // save the last status that we saw so that the
+ // imgRequestProxy will have access to it.
+ if (mRequest) {
+ mRequest = nullptr; // we no longer need the request
+ }
+
+ // stop holding a ref to the channel, since we don't need it anymore
+ if (mChannel) {
+ mChannel->SetNotificationCallbacks(mPrevChannelSink);
+ mPrevChannelSink = nullptr;
+ mChannel = nullptr;
+ }
+
+ bool lastPart = true;
+ nsCOMPtr<nsIMultiPartChannel> mpchan(do_QueryInterface(aRequest));
+ if (mpchan) {
+ mpchan->GetIsLastPart(&lastPart);
+ }
+
+ bool isPartial = false;
+ if (image && (status == NS_ERROR_NET_PARTIAL_TRANSFER)) {
+ isPartial = true;
+ status = NS_OK; // fake happy face
+ }
+
+ // Tell the image that it has all of the source data. Note that this can
+ // trigger a failure, since the image might be waiting for more non-optional
+ // data and this is the point where we break the news that it's not coming.
+ if (image) {
+ nsresult rv = image->OnImageDataComplete(aRequest, status, lastPart);
+
+ // If we got an error in the OnImageDataComplete() call, we don't want to
+ // proceed as if nothing bad happened. However, we also want to give
+ // precedence to failure status codes from necko, since presumably they're
+ // more meaningful.
+ if (NS_FAILED(rv) && NS_SUCCEEDED(status)) {
+ status = rv;
+ }
+ }
+
+ // If the request went through, update the cache entry size. Otherwise,
+ // cancel the request, which removes us from the cache.
+ if (image && NS_SUCCEEDED(status) && !isPartial) {
+ // We update the cache entry size here because this is where we finish
+ // loading compressed source data, which is part of our size calculus.
+ UpdateCacheEntrySize();
+
+ } else if (isPartial) {
+ // Remove the partial image from the cache.
+ this->EvictFromCache();
+
+ } else {
+ mImageErrorCode = status;
+
+ // if the error isn't "just" a partial transfer
+ // stops animations, removes from cache
+ this->Cancel(status);
+ }
+
+ if (!image) {
+ // We have to fire the OnStopRequest notifications ourselves because there's
+ // no image capable of doing so.
+ Progress progress =
+ LoadCompleteProgress(lastPart, /* aError = */ false, status);
+
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ progressTracker->SyncNotifyProgress(progress);
+ }
+
+ mTimedChannel = nullptr;
+ return NS_OK;
+}
+
+struct mimetype_closure {
+ nsACString* newType;
+};
+
+/* prototype for these defined below */
+static nsresult sniff_mimetype_callback(nsIInputStream* in, void* closure,
+ const char* fromRawSegment,
+ uint32_t toOffset, uint32_t count,
+ uint32_t* writeCount);
+
+/** nsThreadRetargetableStreamListener methods **/
+NS_IMETHODIMP
+imgRequest::CheckListenerChain() {
+ // TODO Might need more checking here.
+ NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread!");
+ return NS_OK;
+}
+
+/** nsIStreamListener methods **/
+
+struct NewPartResult final {
+ explicit NewPartResult(image::Image* aExistingImage)
+ : mImage(aExistingImage),
+ mIsFirstPart(!aExistingImage),
+ mSucceeded(false),
+ mShouldResetCacheEntry(false) {}
+
+ nsAutoCString mContentType;
+ nsAutoCString mContentDisposition;
+ RefPtr<image::Image> mImage;
+ const bool mIsFirstPart;
+ bool mSucceeded;
+ bool mShouldResetCacheEntry;
+};
+
+static NewPartResult PrepareForNewPart(nsIRequest* aRequest,
+ nsIInputStream* aInStr, uint32_t aCount,
+ nsIURI* aURI, bool aIsMultipart,
+ image::Image* aExistingImage,
+ ProgressTracker* aProgressTracker,
+ uint64_t aInnerWindowId) {
+ NewPartResult result(aExistingImage);
+
+ if (aInStr) {
+ mimetype_closure closure;
+ closure.newType = &result.mContentType;
+
+ // Look at the first few bytes and see if we can tell what the data is from
+ // that since servers tend to lie. :(
+ uint32_t out;
+ aInStr->ReadSegments(sniff_mimetype_callback, &closure, aCount, &out);
+ }
+
+ nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
+ if (result.mContentType.IsEmpty()) {
+ nsresult rv =
+ chan ? chan->GetContentType(result.mContentType) : NS_ERROR_FAILURE;
+ if (NS_FAILED(rv)) {
+ MOZ_LOG(gImgLog, LogLevel::Error,
+ ("imgRequest::PrepareForNewPart -- "
+ "Content type unavailable from the channel\n"));
+ if (!aIsMultipart) {
+ return result;
+ }
+ }
+ }
+
+ if (chan) {
+ chan->GetContentDispositionHeader(result.mContentDisposition);
+ }
+
+ MOZ_LOG(gImgLog, LogLevel::Debug,
+ ("imgRequest::PrepareForNewPart -- Got content type %s\n",
+ result.mContentType.get()));
+
+ // XXX If server lied about mimetype and it's SVG, we may need to copy
+ // the data and dispatch back to the main thread, AND tell the channel to
+ // dispatch there in the future.
+
+ // Create the new image and give it ownership of our ProgressTracker.
+ if (aIsMultipart) {
+ // Create the ProgressTracker and image for this part.
+ RefPtr<ProgressTracker> progressTracker = new ProgressTracker();
+ RefPtr<image::Image> partImage = image::ImageFactory::CreateImage(
+ aRequest, progressTracker, result.mContentType, aURI,
+ /* aIsMultipart = */ true, aInnerWindowId);
+
+ if (result.mIsFirstPart) {
+ // First part for a multipart channel. Create the MultipartImage wrapper.
+ MOZ_ASSERT(aProgressTracker, "Shouldn't have given away tracker yet");
+ aProgressTracker->SetIsMultipart();
+ result.mImage = image::ImageFactory::CreateMultipartImage(
+ partImage, aProgressTracker);
+ } else {
+ // Transition to the new part.
+ auto multipartImage = static_cast<MultipartImage*>(aExistingImage);
+ multipartImage->BeginTransitionToPart(partImage);
+
+ // Reset our cache entry size so it doesn't keep growing without bound.
+ result.mShouldResetCacheEntry = true;
+ }
+ } else {
+ MOZ_ASSERT(!aExistingImage, "New part for non-multipart channel?");
+ MOZ_ASSERT(aProgressTracker, "Shouldn't have given away tracker yet");
+
+ // Create an image using our progress tracker.
+ result.mImage = image::ImageFactory::CreateImage(
+ aRequest, aProgressTracker, result.mContentType, aURI,
+ /* aIsMultipart = */ false, aInnerWindowId);
+ }
+
+ MOZ_ASSERT(result.mImage);
+ if (!result.mImage->HasError() || aIsMultipart) {
+ // We allow multipart images to fail to initialize (which generally
+ // indicates a bad content type) without cancelling the load, because
+ // subsequent parts might be fine.
+ result.mSucceeded = true;
+ }
+
+ return result;
+}
+
+class FinishPreparingForNewPartRunnable final : public Runnable {
+ public:
+ FinishPreparingForNewPartRunnable(imgRequest* aImgRequest,
+ NewPartResult&& aResult)
+ : Runnable("FinishPreparingForNewPartRunnable"),
+ mImgRequest(aImgRequest),
+ mResult(aResult) {
+ MOZ_ASSERT(aImgRequest);
+ }
+
+ NS_IMETHOD Run() override {
+ mImgRequest->FinishPreparingForNewPart(mResult);
+ return NS_OK;
+ }
+
+ private:
+ RefPtr<imgRequest> mImgRequest;
+ NewPartResult mResult;
+};
+
+void imgRequest::FinishPreparingForNewPart(const NewPartResult& aResult) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ mContentType = aResult.mContentType;
+
+ SetProperties(aResult.mContentType, aResult.mContentDisposition);
+
+ if (aResult.mIsFirstPart) {
+ // Notify listeners that we have an image.
+ mImageAvailable = true;
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ progressTracker->OnImageAvailable();
+ MOZ_ASSERT(progressTracker->HasImage());
+ }
+
+ if (aResult.mShouldResetCacheEntry) {
+ ResetCacheEntry();
+ }
+
+ if (IsDecodeRequested()) {
+ aResult.mImage->StartDecoding(imgIContainer::FLAG_NONE);
+ }
+}
+
+bool imgRequest::ImageAvailable() const { return mImageAvailable; }
+
+NS_IMETHODIMP
+imgRequest::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInStr,
+ uint64_t aOffset, uint32_t aCount) {
+ LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::OnDataAvailable", "count", aCount);
+
+ NS_ASSERTION(aRequest, "imgRequest::OnDataAvailable -- no request!");
+
+ RefPtr<Image> image;
+ RefPtr<ProgressTracker> progressTracker;
+ bool isMultipart = false;
+ bool newPartPending = false;
+ uint64_t innerWindowId = 0;
+
+ // Retrieve and update our state.
+ {
+ MutexAutoLock lock(mMutex);
+ image = mImage;
+ progressTracker = mProgressTracker;
+ isMultipart = mIsMultiPartChannel;
+ newPartPending = mNewPartPending;
+ mNewPartPending = false;
+ innerWindowId = mInnerWindowId;
+ }
+
+ // If this is a new part, we need to sniff its content type and create an
+ // appropriate image.
+ if (newPartPending) {
+ NewPartResult result =
+ PrepareForNewPart(aRequest, aInStr, aCount, mURI, isMultipart, image,
+ progressTracker, innerWindowId);
+ bool succeeded = result.mSucceeded;
+
+ if (result.mImage) {
+ image = result.mImage;
+ nsCOMPtr<nsIEventTarget> eventTarget;
+
+ // Update our state to reflect this new part.
+ {
+ MutexAutoLock lock(mMutex);
+ mImage = image;
+
+ // We only get an event target if we are not on the main thread, because
+ // we have to dispatch in that case. If we are on the main thread, but
+ // on a different scheduler group than ProgressTracker would give us,
+ // that is okay because nothing in imagelib requires that, just our
+ // listeners (which have their own checks).
+ if (!NS_IsMainThread()) {
+ eventTarget = mProgressTracker->GetEventTarget();
+ MOZ_ASSERT(eventTarget);
+ }
+
+ mProgressTracker = nullptr;
+ }
+
+ // Some property objects are not threadsafe, and we need to send
+ // OnImageAvailable on the main thread, so finish on the main thread.
+ if (!eventTarget) {
+ MOZ_ASSERT(NS_IsMainThread());
+ FinishPreparingForNewPart(result);
+ } else {
+ nsCOMPtr<nsIRunnable> runnable =
+ new FinishPreparingForNewPartRunnable(this, std::move(result));
+ eventTarget->Dispatch(CreateRenderBlockingRunnable(runnable.forget()),
+ NS_DISPATCH_NORMAL);
+ }
+ }
+
+ if (!succeeded) {
+ // Something went wrong; probably a content type issue.
+ Cancel(NS_IMAGELIB_ERROR_FAILURE);
+ return NS_BINDING_ABORTED;
+ }
+ }
+
+ // Notify the image that it has new data.
+ if (aInStr) {
+ nsresult rv =
+ image->OnImageDataAvailable(aRequest, aInStr, aOffset, aCount);
+
+ if (NS_FAILED(rv)) {
+ MOZ_LOG(gImgLog, LogLevel::Warning,
+ ("[this=%p] imgRequest::OnDataAvailable -- "
+ "copy to RasterImage failed\n",
+ this));
+ Cancel(NS_IMAGELIB_ERROR_FAILURE);
+ return NS_BINDING_ABORTED;
+ }
+ }
+
+ return NS_OK;
+}
+
+void imgRequest::SetProperties(const nsACString& aContentType,
+ const nsACString& aContentDisposition) {
+ /* set our mimetype as a property */
+ nsCOMPtr<nsISupportsCString> contentType =
+ do_CreateInstance("@mozilla.org/supports-cstring;1");
+ if (contentType) {
+ contentType->SetData(aContentType);
+ mProperties->Set("type", contentType);
+ }
+
+ /* set our content disposition as a property */
+ if (!aContentDisposition.IsEmpty()) {
+ nsCOMPtr<nsISupportsCString> contentDisposition =
+ do_CreateInstance("@mozilla.org/supports-cstring;1");
+ if (contentDisposition) {
+ contentDisposition->SetData(aContentDisposition);
+ mProperties->Set("content-disposition", contentDisposition);
+ }
+ }
+}
+
+static nsresult sniff_mimetype_callback(nsIInputStream* in, void* data,
+ const char* fromRawSegment,
+ uint32_t toOffset, uint32_t count,
+ uint32_t* writeCount) {
+ mimetype_closure* closure = static_cast<mimetype_closure*>(data);
+
+ NS_ASSERTION(closure, "closure is null!");
+
+ if (count > 0) {
+ imgLoader::GetMimeTypeFromContent(fromRawSegment, count, *closure->newType);
+ }
+
+ *writeCount = 0;
+ return NS_ERROR_FAILURE;
+}
+
+/** nsIInterfaceRequestor methods **/
+
+NS_IMETHODIMP
+imgRequest::GetInterface(const nsIID& aIID, void** aResult) {
+ if (!mPrevChannelSink || aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
+ return QueryInterface(aIID, aResult);
+ }
+
+ NS_ASSERTION(
+ mPrevChannelSink != this,
+ "Infinite recursion - don't keep track of channel sinks that are us!");
+ return mPrevChannelSink->GetInterface(aIID, aResult);
+}
+
+/** nsIChannelEventSink methods **/
+NS_IMETHODIMP
+imgRequest::AsyncOnChannelRedirect(nsIChannel* oldChannel,
+ nsIChannel* newChannel, uint32_t flags,
+ nsIAsyncVerifyRedirectCallback* callback) {
+ NS_ASSERTION(mRequest && mChannel,
+ "Got a channel redirect after we nulled out mRequest!");
+ NS_ASSERTION(mChannel == oldChannel,
+ "Got a channel redirect for an unknown channel!");
+ NS_ASSERTION(newChannel, "Got a redirect to a NULL channel!");
+
+ SetCacheValidation(mCacheEntry, oldChannel);
+
+ // Prepare for callback
+ mRedirectCallback = callback;
+ mNewRedirectChannel = newChannel;
+
+ nsCOMPtr<nsIChannelEventSink> sink(do_GetInterface(mPrevChannelSink));
+ if (sink) {
+ nsresult rv =
+ sink->AsyncOnChannelRedirect(oldChannel, newChannel, flags, this);
+ if (NS_FAILED(rv)) {
+ mRedirectCallback = nullptr;
+ mNewRedirectChannel = nullptr;
+ }
+ return rv;
+ }
+
+ (void)OnRedirectVerifyCallback(NS_OK);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequest::OnRedirectVerifyCallback(nsresult result) {
+ NS_ASSERTION(mRedirectCallback, "mRedirectCallback not set in callback");
+ NS_ASSERTION(mNewRedirectChannel, "mNewRedirectChannel not set in callback");
+
+ if (NS_FAILED(result)) {
+ mRedirectCallback->OnRedirectVerifyCallback(result);
+ mRedirectCallback = nullptr;
+ mNewRedirectChannel = nullptr;
+ return NS_OK;
+ }
+
+ mChannel = mNewRedirectChannel;
+ mTimedChannel = do_QueryInterface(mChannel);
+ mNewRedirectChannel = nullptr;
+
+ if (LOG_TEST(LogLevel::Debug)) {
+ LOG_MSG_WITH_PARAM(gImgLog, "imgRequest::OnChannelRedirect", "old",
+ mFinalURI ? mFinalURI->GetSpecOrDefault().get() : "");
+ }
+
+ // If the previous URI is a non-HTTPS URI, record that fact for later use by
+ // security code, which needs to know whether there is an insecure load at any
+ // point in the redirect chain.
+ bool schemeLocal = false;
+ if (NS_FAILED(NS_URIChainHasFlags(mFinalURI,
+ nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
+ &schemeLocal)) ||
+ (!mFinalURI->SchemeIs("https") && !mFinalURI->SchemeIs("chrome") &&
+ !schemeLocal)) {
+ MutexAutoLock lock(mMutex);
+
+ // The csp directive upgrade-insecure-requests performs an internal redirect
+ // to upgrade all requests from http to https before any data is fetched
+ // from the network. Do not pollute mHadInsecureRedirect in case of such an
+ // internal redirect.
+ nsCOMPtr<nsILoadInfo> loadInfo = mChannel->LoadInfo();
+ bool upgradeInsecureRequests =
+ loadInfo ? loadInfo->GetUpgradeInsecureRequests() ||
+ loadInfo->GetBrowserUpgradeInsecureRequests()
+ : false;
+ if (!upgradeInsecureRequests) {
+ mHadInsecureRedirect = true;
+ }
+ }
+
+ // Update the final URI.
+ mChannel->GetURI(getter_AddRefs(mFinalURI));
+
+ if (LOG_TEST(LogLevel::Debug)) {
+ LOG_MSG_WITH_PARAM(gImgLog, "imgRequest::OnChannelRedirect", "new",
+ mFinalURI ? mFinalURI->GetSpecOrDefault().get() : "");
+ }
+
+ // Make sure we have a protocol that returns data rather than opens an
+ // external application, e.g. 'mailto:'.
+ if (nsContentUtils::IsExternalProtocol(mFinalURI)) {
+ mRedirectCallback->OnRedirectVerifyCallback(NS_ERROR_ABORT);
+ mRedirectCallback = nullptr;
+ return NS_OK;
+ }
+
+ mRedirectCallback->OnRedirectVerifyCallback(NS_OK);
+ mRedirectCallback = nullptr;
+ return NS_OK;
+}
diff --git a/image/imgRequest.h b/image/imgRequest.h
new file mode 100644
index 0000000000..de2d5b457c
--- /dev/null
+++ b/image/imgRequest.h
@@ -0,0 +1,296 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_imgRequest_h
+#define mozilla_image_imgRequest_h
+
+#include "nsIChannelEventSink.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsIStreamListener.h"
+#include "nsIThreadRetargetableStreamListener.h"
+#include "nsIPrincipal.h"
+
+#include "nsCOMPtr.h"
+#include "nsProxyRelease.h"
+#include "nsString.h"
+#include "nsError.h"
+#include "nsIAsyncVerifyRedirectCallback.h"
+#include "mozilla/Mutex.h"
+#include "ImageCacheKey.h"
+
+class imgCacheValidator;
+class imgLoader;
+class imgRequestProxy;
+class imgCacheEntry;
+class nsIProperties;
+class nsIRequest;
+class nsITimedChannel;
+class nsIURI;
+class nsIReferrerInfo;
+
+namespace mozilla {
+enum CORSMode : uint8_t;
+namespace image {
+class Image;
+class ProgressTracker;
+} // namespace image
+} // namespace mozilla
+
+struct NewPartResult;
+
+class imgRequest final : public nsIStreamListener,
+ public nsIThreadRetargetableStreamListener,
+ public nsIChannelEventSink,
+ public nsIInterfaceRequestor,
+ public nsIAsyncVerifyRedirectCallback {
+ typedef mozilla::image::Image Image;
+ typedef mozilla::image::ImageCacheKey ImageCacheKey;
+ typedef mozilla::image::ProgressTracker ProgressTracker;
+ typedef mozilla::dom::ReferrerPolicy ReferrerPolicy;
+
+ public:
+ imgRequest(imgLoader* aLoader, const ImageCacheKey& aCacheKey);
+
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSISTREAMLISTENER
+ NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSICHANNELEVENTSINK
+ NS_DECL_NSIINTERFACEREQUESTOR
+ NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
+
+ [[nodiscard]] nsresult Init(nsIURI* aURI, nsIURI* aFinalURI,
+ bool aHadInsecureRedirect, nsIRequest* aRequest,
+ nsIChannel* aChannel, imgCacheEntry* aCacheEntry,
+ mozilla::dom::Document* aLoadingDocument,
+ nsIPrincipal* aTriggeringPrincipal,
+ mozilla::CORSMode aCORSMode,
+ nsIReferrerInfo* aReferrerInfo);
+
+ void ClearLoader();
+
+ // Callers must call imgRequestProxy::Notify later.
+ void AddProxy(imgRequestProxy* proxy);
+
+ // Whether a given document is allowed to reuse this request without any
+ // revalidation.
+ bool CanReuseWithoutValidation(mozilla::dom::Document*) const;
+
+ nsresult RemoveProxy(imgRequestProxy* proxy, nsresult aStatus);
+
+ // Cancel, but also ensure that all work done in Init() is undone. Call this
+ // only when the channel has failed to open, and so calling Cancel() on it
+ // won't be sufficient.
+ void CancelAndAbort(nsresult aStatus);
+
+ // Called or dispatched by cancel for main thread only execution.
+ void ContinueCancel(nsresult aStatus);
+
+ // Called or dispatched by EvictFromCache for main thread only execution.
+ void ContinueEvict();
+
+ // Request that we start decoding the image as soon as data becomes available.
+ void StartDecoding();
+
+ uint64_t InnerWindowID() const;
+ void SetInnerWindowID(uint64_t aInnerWindowId);
+
+ // Set the cache validation information (expiry time, whether we must
+ // validate, etc) on the cache entry based on the request information.
+ // If this function is called multiple times, the information set earliest
+ // wins.
+ static void SetCacheValidation(imgCacheEntry* aEntry, nsIRequest* aRequest);
+
+ bool GetMultipart() const;
+
+ // Returns whether we went through an insecure (non-HTTPS) redirect at some
+ // point during loading. This does not consider the final URI.
+ bool HadInsecureRedirect() const;
+
+ // The CORS mode for which we loaded this image.
+ mozilla::CORSMode GetCORSMode() const { return mCORSMode; }
+
+ // The ReferrerInfo in effect when loading this image.
+ nsIReferrerInfo* GetReferrerInfo() const { return mReferrerInfo; }
+
+ // The principal for the document that loaded this image. Used when trying to
+ // validate a CORS image load.
+ already_AddRefed<nsIPrincipal> GetTriggeringPrincipal() const;
+
+ // Return the ProgressTracker associated with this imgRequest. It may live
+ // in |mProgressTracker| or in |mImage.mProgressTracker|, depending on whether
+ // mImage has been instantiated yet.
+ already_AddRefed<ProgressTracker> GetProgressTracker() const;
+
+ /// Returns the Image associated with this imgRequest, if it's ready.
+ already_AddRefed<Image> GetImage() const;
+
+ // Get the current principal of the image. No AddRefing.
+ inline nsIPrincipal* GetPrincipal() const { return mPrincipal.get(); }
+
+ /// Get the ImageCacheKey associated with this request.
+ const ImageCacheKey& CacheKey() const { return mCacheKey; }
+
+ // Resize the cache entry to 0 if it exists
+ void ResetCacheEntry();
+
+ // OK to use on any thread.
+ nsresult GetURI(nsIURI** aURI);
+ nsresult GetFinalURI(nsIURI** aURI);
+ bool IsChrome() const;
+ bool IsData() const;
+
+ nsresult GetImageErrorCode(void);
+
+ /// Returns a non-owning pointer to this imgRequest's MIME type.
+ const char* GetMimeType() const { return mContentType.get(); }
+
+ void GetFileName(nsACString& aFileName);
+
+ /// @return the priority of the underlying network request, or
+ /// PRIORITY_NORMAL if it doesn't support nsISupportsPriority.
+ int32_t Priority() const;
+
+ /// Adjust the priority of the underlying network request by @aDelta on behalf
+ /// of @aProxy.
+ void AdjustPriority(imgRequestProxy* aProxy, int32_t aDelta);
+
+ void BoostPriority(uint32_t aCategory);
+
+ /// Returns a weak pointer to the underlying request.
+ nsIRequest* GetRequest() const { return mRequest; }
+
+ nsITimedChannel* GetTimedChannel() const { return mTimedChannel; }
+
+ imgCacheValidator* GetValidator() const { return mValidator; }
+ void SetValidator(imgCacheValidator* aValidator) { mValidator = aValidator; }
+
+ void* LoadId() const { return mLoadId; }
+ void SetLoadId(void* aLoadId) { mLoadId = aLoadId; }
+
+ /// Reset the cache entry after we've dropped our reference to it. Used by
+ /// imgLoader when our cache entry is re-requested after we've dropped our
+ /// reference to it.
+ void SetCacheEntry(imgCacheEntry* aEntry);
+
+ /// Returns whether we've got a reference to the cache entry.
+ bool HasCacheEntry() const;
+
+ /// Set whether this request is stored in the cache. If it isn't, regardless
+ /// of whether this request has a non-null mCacheEntry, this imgRequest won't
+ /// try to update or modify the image cache.
+ void SetIsInCache(bool aCacheable);
+
+ void EvictFromCache();
+ void RemoveFromCache();
+
+ // Sets properties for this image; will dispatch to main thread if needed.
+ void SetProperties(const nsACString& aContentType,
+ const nsACString& aContentDisposition);
+
+ nsIProperties* Properties() const { return mProperties; }
+
+ bool HasConsumers() const;
+
+ bool ImageAvailable() const;
+
+ bool IsDeniedCrossSiteCORSRequest() const {
+ return mIsDeniedCrossSiteCORSRequest;
+ }
+
+ bool IsCrossSiteNoCORSRequest() const { return mIsCrossSiteNoCORSRequest; }
+
+ private:
+ friend class FinishPreparingForNewPartRunnable;
+
+ virtual ~imgRequest();
+
+ void FinishPreparingForNewPart(const NewPartResult& aResult);
+
+ void Cancel(nsresult aStatus);
+
+ // Update the cache entry size based on the image container.
+ void UpdateCacheEntrySize();
+
+ /// Returns true if StartDecoding() was called.
+ bool IsDecodeRequested() const;
+
+ void AdjustPriorityInternal(int32_t aDelta);
+
+ // Weak reference to parent loader; this request cannot outlive its owner.
+ imgLoader* mLoader;
+ nsCOMPtr<nsIRequest> mRequest;
+ // The original URI we were loaded with. This is the same as the URI we are
+ // keyed on in the cache. We store a string here to avoid off main thread
+ // refcounting issues with nsStandardURL.
+ nsCOMPtr<nsIURI> mURI;
+ // The URI of the resource we ended up loading after all redirects, etc.
+ nsCOMPtr<nsIURI> mFinalURI;
+ // The principal which triggered the load of this image. Generally either
+ // the principal of the document the image is being loaded into, or of the
+ // stylesheet which specified the image to load. Used when validating for
+ // CORS.
+ nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
+ // The principal of this image.
+ nsCOMPtr<nsIPrincipal> mPrincipal;
+ nsCOMPtr<nsIProperties> mProperties;
+ nsCOMPtr<nsIChannel> mChannel;
+ nsCOMPtr<nsIInterfaceRequestor> mPrevChannelSink;
+
+ nsCOMPtr<nsITimedChannel> mTimedChannel;
+
+ nsCString mContentType;
+
+ /* we hold on to this to this so long as we have observers */
+ RefPtr<imgCacheEntry> mCacheEntry;
+
+ /// The key under which this imgRequest is stored in the image cache.
+ ImageCacheKey mCacheKey;
+
+ void* mLoadId;
+
+ /// Raw pointer to the first proxy that was added to this imgRequest. Use only
+ /// pointer comparisons; there's no guarantee this will remain valid.
+ void* mFirstProxy;
+
+ imgCacheValidator* mValidator;
+ nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
+ nsCOMPtr<nsIChannel> mNewRedirectChannel;
+
+ // The CORS mode (defined in imgIRequest) this image was loaded with. By
+ // default, CORS_NONE.
+ mozilla::CORSMode mCORSMode;
+
+ // The ReferrerInfo used for this image.
+ nsCOMPtr<nsIReferrerInfo> mReferrerInfo;
+
+ nsresult mImageErrorCode;
+
+ // The categories of prioritization strategy that have been requested.
+ uint32_t mBoostCategoriesRequested = 0;
+
+ // If we've called OnImageAvailable.
+ bool mImageAvailable;
+ bool mIsDeniedCrossSiteCORSRequest;
+ bool mIsCrossSiteNoCORSRequest;
+
+ mutable mozilla::Mutex mMutex;
+
+ // Member variables protected by mMutex. Note that *all* flags in our bitfield
+ // are protected by mMutex; if you're adding a new flag that isn'protected, it
+ // must not be a part of this bitfield.
+ RefPtr<ProgressTracker> mProgressTracker MOZ_GUARDED_BY(mMutex);
+ RefPtr<Image> mImage MOZ_GUARDED_BY(mMutex);
+ bool mIsMultiPartChannel : 1 MOZ_GUARDED_BY(mMutex);
+ bool mIsInCache : 1 MOZ_GUARDED_BY(mMutex);
+ bool mDecodeRequested : 1 MOZ_GUARDED_BY(mMutex);
+ bool mNewPartPending : 1 MOZ_GUARDED_BY(mMutex);
+ bool mHadInsecureRedirect : 1 MOZ_GUARDED_BY(mMutex);
+ // The ID of the inner window origin, used for error reporting.
+ uint64_t mInnerWindowId MOZ_GUARDED_BY(mMutex);
+};
+
+#endif // mozilla_image_imgRequest_h
diff --git a/image/imgRequestProxy.cpp b/image/imgRequestProxy.cpp
new file mode 100644
index 0000000000..797ae918a9
--- /dev/null
+++ b/image/imgRequestProxy.cpp
@@ -0,0 +1,1327 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "imgRequestProxy.h"
+
+#include <utility>
+
+#include "Image.h"
+#include "ImageLogging.h"
+#include "ImageOps.h"
+#include "ImageTypes.h"
+#include "imgINotificationObserver.h"
+#include "imgLoader.h"
+#include "mozilla/dom/Document.h"
+#include "mozilla/Telemetry.h" // for Telemetry
+#include "mozilla/dom/DocGroup.h" // for DocGroup
+#include "nsCRTGlue.h"
+#include "nsError.h"
+
+using namespace mozilla;
+using namespace mozilla::image;
+
+// The split of imgRequestProxy and imgRequestProxyStatic means that
+// certain overridden functions need to be usable in the destructor.
+// Since virtual functions can't be used in that way, this class
+// provides a behavioural trait for each class to use instead.
+class ProxyBehaviour {
+ public:
+ virtual ~ProxyBehaviour() = default;
+
+ virtual already_AddRefed<mozilla::image::Image> GetImage() const = 0;
+ virtual bool HasImage() const = 0;
+ virtual already_AddRefed<ProgressTracker> GetProgressTracker() const = 0;
+ virtual imgRequest* GetOwner() const = 0;
+ virtual void SetOwner(imgRequest* aOwner) = 0;
+};
+
+class RequestBehaviour : public ProxyBehaviour {
+ public:
+ RequestBehaviour() : mOwner(nullptr), mOwnerHasImage(false) {}
+
+ already_AddRefed<mozilla::image::Image> GetImage() const override;
+ bool HasImage() const override;
+ already_AddRefed<ProgressTracker> GetProgressTracker() const override;
+
+ imgRequest* GetOwner() const override { return mOwner; }
+
+ void SetOwner(imgRequest* aOwner) override {
+ mOwner = aOwner;
+
+ if (mOwner) {
+ RefPtr<ProgressTracker> ownerProgressTracker = GetProgressTracker();
+ mOwnerHasImage = ownerProgressTracker && ownerProgressTracker->HasImage();
+ } else {
+ mOwnerHasImage = false;
+ }
+ }
+
+ private:
+ // We maintain the following invariant:
+ // The proxy is registered at most with a single imgRequest as an observer,
+ // and whenever it is, mOwner points to that object. This helps ensure that
+ // imgRequestProxy::~imgRequestProxy unregisters the proxy as an observer
+ // from whatever request it was registered with (if any). This, in turn,
+ // means that imgRequest::mObservers will not have any stale pointers in it.
+ RefPtr<imgRequest> mOwner;
+
+ bool mOwnerHasImage;
+};
+
+already_AddRefed<mozilla::image::Image> RequestBehaviour::GetImage() const {
+ if (!mOwnerHasImage) {
+ return nullptr;
+ }
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ return progressTracker->GetImage();
+}
+
+already_AddRefed<ProgressTracker> RequestBehaviour::GetProgressTracker() const {
+ // NOTE: It's possible that our mOwner has an Image that it didn't notify
+ // us about, if we were Canceled before its Image was constructed.
+ // (Canceling removes us as an observer, so mOwner has no way to notify us).
+ // That's why this method uses mOwner->GetProgressTracker() instead of just
+ // mOwner->mProgressTracker -- we might have a null mImage and yet have an
+ // mOwner with a non-null mImage (and a null mProgressTracker pointer).
+ return mOwner->GetProgressTracker();
+}
+
+NS_IMPL_ADDREF(imgRequestProxy)
+NS_IMPL_RELEASE(imgRequestProxy)
+
+NS_INTERFACE_MAP_BEGIN(imgRequestProxy)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, PreloaderBase)
+ NS_INTERFACE_MAP_ENTRY(imgIRequest)
+ NS_INTERFACE_MAP_ENTRY(nsIRequest)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)
+ NS_INTERFACE_MAP_ENTRY_CONCRETE(imgRequestProxy)
+ NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsITimedChannel, TimedChannel() != nullptr)
+NS_INTERFACE_MAP_END
+
+imgRequestProxy::imgRequestProxy()
+ : mBehaviour(new RequestBehaviour),
+ mURI(nullptr),
+ mListener(nullptr),
+ mLoadFlags(nsIRequest::LOAD_NORMAL),
+ mLockCount(0),
+ mAnimationConsumers(0),
+ mCancelable(true),
+ mCanceled(false),
+ mIsInLoadGroup(false),
+ mForceDispatchLoadGroup(false),
+ mListenerIsStrongRef(false),
+ mDecodeRequested(false),
+ mPendingNotify(false),
+ mValidating(false),
+ mHadListener(false),
+ mHadDispatch(false) {
+ /* member initializers and constructor code */
+ LOG_FUNC(gImgLog, "imgRequestProxy::imgRequestProxy");
+}
+
+imgRequestProxy::~imgRequestProxy() {
+ /* destructor code */
+ MOZ_ASSERT(!mListener, "Someone forgot to properly cancel this request!");
+
+ // If we had a listener, that means we would have issued notifications. With
+ // bug 1359833, we added support for main thread scheduler groups. Each
+ // imgRequestProxy may have its own associated listener, document and/or
+ // scheduler group. Typically most imgRequestProxy belong to the same
+ // document, or have no listener, which means we will want to execute all main
+ // thread code in that shared scheduler group. Less frequently, there may be
+ // multiple imgRequests and they have separate documents, which means that
+ // when we issue state notifications, some or all need to be dispatched to the
+ // appropriate scheduler group for each request. This should be rare, so we
+ // want to monitor the frequency of dispatching in the wild.
+ if (mHadListener) {
+ mozilla::Telemetry::Accumulate(mozilla::Telemetry::IMAGE_REQUEST_DISPATCHED,
+ mHadDispatch);
+ }
+
+ MOZ_RELEASE_ASSERT(!mLockCount, "Someone forgot to unlock on time?");
+
+ ClearAnimationConsumers();
+
+ // Explicitly set mListener to null to ensure that the RemoveProxy
+ // call below can't send |this| to an arbitrary listener while |this|
+ // is being destroyed. This is all belt-and-suspenders in view of the
+ // above assert.
+ NullOutListener();
+
+ /* Call RemoveProxy with a successful status. This will keep the
+ channel, if still downloading data, from being canceled if 'this' is
+ the last observer. This allows the image to continue to download and
+ be cached even if no one is using it currently.
+ */
+ mCanceled = true;
+ RemoveFromOwner(NS_OK);
+
+ RemoveFromLoadGroup();
+ LOG_FUNC(gImgLog, "imgRequestProxy::~imgRequestProxy");
+}
+
+nsresult imgRequestProxy::Init(imgRequest* aOwner, nsILoadGroup* aLoadGroup,
+ Document* aLoadingDocument, nsIURI* aURI,
+ imgINotificationObserver* aObserver) {
+ MOZ_ASSERT(!GetOwner() && !mListener,
+ "imgRequestProxy is already initialized");
+
+ LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequestProxy::Init", "request", aOwner);
+
+ MOZ_ASSERT(mAnimationConsumers == 0, "Cannot have animation before Init");
+
+ mBehaviour->SetOwner(aOwner);
+ mListener = aObserver;
+ // Make sure to addref mListener before the AddToOwner call below, since
+ // that call might well want to release it if the imgRequest has
+ // already seen OnStopRequest.
+ if (mListener) {
+ mHadListener = true;
+ mListenerIsStrongRef = true;
+ NS_ADDREF(mListener);
+ }
+ mLoadGroup = aLoadGroup;
+ mURI = aURI;
+
+ // Note: AddToOwner won't send all the On* notifications immediately
+ AddToOwner(aLoadingDocument);
+
+ return NS_OK;
+}
+
+nsresult imgRequestProxy::ChangeOwner(imgRequest* aNewOwner) {
+ MOZ_ASSERT(GetOwner(), "Cannot ChangeOwner on a proxy without an owner!");
+
+ if (mCanceled) {
+ // Ensure that this proxy has received all notifications to date
+ // before we clean it up when removing it from the old owner below.
+ SyncNotifyListener();
+ }
+
+ // If we're holding locks, unlock the old image.
+ // Note that UnlockImage decrements mLockCount each time it's called.
+ uint32_t oldLockCount = mLockCount;
+ while (mLockCount) {
+ UnlockImage();
+ }
+
+ // If we're holding animation requests, undo them.
+ uint32_t oldAnimationConsumers = mAnimationConsumers;
+ ClearAnimationConsumers();
+
+ GetOwner()->RemoveProxy(this, NS_OK);
+
+ mBehaviour->SetOwner(aNewOwner);
+ MOZ_ASSERT(!GetValidator(), "New owner cannot be validating!");
+
+ // If we were locked, apply the locks here
+ for (uint32_t i = 0; i < oldLockCount; i++) {
+ LockImage();
+ }
+
+ // If we had animation requests, restore them here. Note that we
+ // do this *after* RemoveProxy, which clears out animation consumers
+ // (see bug 601723).
+ for (uint32_t i = 0; i < oldAnimationConsumers; i++) {
+ IncrementAnimationConsumers();
+ }
+
+ AddToOwner(nullptr);
+ return NS_OK;
+}
+
+NS_IMETHODIMP imgRequestProxy::GetTriggeringPrincipal(
+ nsIPrincipal** aTriggeringPrincipal) {
+ MOZ_ASSERT(GetOwner());
+ nsCOMPtr<nsIPrincipal> triggeringPrincipal =
+ GetOwner()->GetTriggeringPrincipal();
+ triggeringPrincipal.forget(aTriggeringPrincipal);
+ return NS_OK;
+}
+
+void imgRequestProxy::MarkValidating() {
+ MOZ_ASSERT(GetValidator());
+ mValidating = true;
+}
+
+void imgRequestProxy::ClearValidating() {
+ MOZ_ASSERT(mValidating);
+ MOZ_ASSERT(!GetValidator());
+ mValidating = false;
+
+ // If we'd previously requested a synchronous decode, request a decode on the
+ // new image.
+ if (mDecodeRequested) {
+ mDecodeRequested = false;
+ StartDecoding(imgIContainer::FLAG_NONE);
+ }
+}
+
+already_AddRefed<nsIEventTarget> imgRequestProxy::GetEventTarget() const {
+ nsCOMPtr<nsIEventTarget> target(mEventTarget);
+ return target.forget();
+}
+
+bool imgRequestProxy::HasDecodedPixels() {
+ if (IsValidating()) {
+ return false;
+ }
+
+ RefPtr<Image> image = GetImage();
+ if (image) {
+ return image->HasDecodedPixels();
+ }
+
+ return false;
+}
+
+nsresult imgRequestProxy::DispatchWithTargetIfAvailable(
+ already_AddRefed<nsIRunnable> aEvent) {
+ LOG_FUNC(gImgLog, "imgRequestProxy::DispatchWithTargetIfAvailable");
+
+ // This method should only be used when it is *expected* that we are
+ // dispatching an event (e.g. we want to handle an event asynchronously)
+ // rather we need to (e.g. we are in the wrong scheduler group context).
+ // As such, we do not set mHadDispatch for telemetry purposes.
+ if (mEventTarget) {
+ mEventTarget->Dispatch(CreateRenderBlockingRunnable(std::move(aEvent)),
+ NS_DISPATCH_NORMAL);
+ return NS_OK;
+ }
+
+ return NS_DispatchToMainThread(
+ CreateRenderBlockingRunnable(std::move(aEvent)));
+}
+
+void imgRequestProxy::AddToOwner(Document* aLoadingDocument) {
+ // An imgRequestProxy can be initialized with neither a listener nor a
+ // document. The caller could follow up later by cloning the canonical
+ // imgRequestProxy with the actual listener. This is possible because
+ // imgLoader::LoadImage does not require a valid listener to be provided.
+ //
+ // Without a listener, we don't need to set our scheduler group, because
+ // we have nothing to signal. However if we were told what document this
+ // is for, it is likely that future listeners will belong to the same
+ // scheduler group.
+ //
+ // With a listener, we always need to update our scheduler group. A null
+ // scheduler group is valid with or without a document, but that means
+ // we will use the most generic event target possible on dispatch.
+ if (aLoadingDocument) {
+ RefPtr<mozilla::dom::DocGroup> docGroup = aLoadingDocument->GetDocGroup();
+ if (docGroup) {
+ mEventTarget = docGroup->EventTargetFor(mozilla::TaskCategory::Other);
+ MOZ_ASSERT(mEventTarget);
+ }
+ }
+
+ if (mListener && !mEventTarget) {
+ mEventTarget = do_GetMainThread();
+ }
+
+ imgRequest* owner = GetOwner();
+ if (!owner) {
+ return;
+ }
+
+ owner->AddProxy(this);
+}
+
+void imgRequestProxy::RemoveFromOwner(nsresult aStatus) {
+ imgRequest* owner = GetOwner();
+ if (owner) {
+ if (mValidating) {
+ imgCacheValidator* validator = owner->GetValidator();
+ MOZ_ASSERT(validator);
+ validator->RemoveProxy(this);
+ mValidating = false;
+ }
+
+ owner->RemoveProxy(this, aStatus);
+ }
+}
+
+void imgRequestProxy::AddToLoadGroup() {
+ NS_ASSERTION(!mIsInLoadGroup, "Whaa, we're already in the loadgroup!");
+ MOZ_ASSERT(!mForceDispatchLoadGroup);
+
+ /* While in theory there could be a dispatch outstanding to remove this
+ request from the load group, in practice we only add to the load group
+ (when previously not in a load group) at initialization. */
+ if (!mIsInLoadGroup && mLoadGroup) {
+ LOG_FUNC(gImgLog, "imgRequestProxy::AddToLoadGroup");
+ mLoadGroup->AddRequest(this, nullptr);
+ mIsInLoadGroup = true;
+ }
+}
+
+void imgRequestProxy::RemoveFromLoadGroup() {
+ if (!mIsInLoadGroup || !mLoadGroup) {
+ return;
+ }
+
+ /* Sometimes we may not be able to remove ourselves from the load group in
+ the current context. This is because our listeners are not re-entrant (e.g.
+ we are in the middle of CancelAndForgetObserver or SyncClone). */
+ if (mForceDispatchLoadGroup) {
+ LOG_FUNC(gImgLog, "imgRequestProxy::RemoveFromLoadGroup -- dispatch");
+
+ /* We take away the load group from the request temporarily; this prevents
+ additional dispatches via RemoveFromLoadGroup occurring, as well as
+ MoveToBackgroundInLoadGroup from removing and readding. This is safe
+ because we know that once we get here, blocking the load group at all is
+ unnecessary. */
+ mIsInLoadGroup = false;
+ nsCOMPtr<nsILoadGroup> loadGroup = std::move(mLoadGroup);
+ RefPtr<imgRequestProxy> self(this);
+ DispatchWithTargetIfAvailable(NS_NewRunnableFunction(
+ "imgRequestProxy::RemoveFromLoadGroup", [self, loadGroup]() -> void {
+ loadGroup->RemoveRequest(self, nullptr, NS_OK);
+ }));
+ return;
+ }
+
+ LOG_FUNC(gImgLog, "imgRequestProxy::RemoveFromLoadGroup");
+
+ /* calling RemoveFromLoadGroup may cause the document to finish
+ loading, which could result in our death. We need to make sure
+ that we stay alive long enough to fight another battle... at
+ least until we exit this function. */
+ nsCOMPtr<imgIRequest> kungFuDeathGrip(this);
+ mLoadGroup->RemoveRequest(this, nullptr, NS_OK);
+ mLoadGroup = nullptr;
+ mIsInLoadGroup = false;
+}
+
+void imgRequestProxy::MoveToBackgroundInLoadGroup() {
+ /* Even if we are still in the load group, we may have taken away the load
+ group reference itself because we are in the process of leaving the group.
+ In that case, there is no need to background the request. */
+ if (!mLoadGroup) {
+ return;
+ }
+
+ /* There is no need to dispatch if we only need to add ourselves to the load
+ group without removal. It is the removal which causes the problematic
+ callbacks (see RemoveFromLoadGroup). */
+ if (mIsInLoadGroup && mForceDispatchLoadGroup) {
+ LOG_FUNC(gImgLog,
+ "imgRequestProxy::MoveToBackgroundInLoadGroup -- dispatch");
+
+ RefPtr<imgRequestProxy> self(this);
+ DispatchWithTargetIfAvailable(NS_NewRunnableFunction(
+ "imgRequestProxy::MoveToBackgroundInLoadGroup",
+ [self]() -> void { self->MoveToBackgroundInLoadGroup(); }));
+ return;
+ }
+
+ LOG_FUNC(gImgLog, "imgRequestProxy::MoveToBackgroundInLoadGroup");
+ nsCOMPtr<imgIRequest> kungFuDeathGrip(this);
+ if (mIsInLoadGroup) {
+ mLoadGroup->RemoveRequest(this, nullptr, NS_OK);
+ }
+
+ mLoadFlags |= nsIRequest::LOAD_BACKGROUND;
+ mLoadGroup->AddRequest(this, nullptr);
+}
+
+/** nsIRequest / imgIRequest methods **/
+
+NS_IMETHODIMP
+imgRequestProxy::GetName(nsACString& aName) {
+ aName.Truncate();
+
+ if (mURI) {
+ mURI->GetSpec(aName);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::IsPending(bool* _retval) { return NS_ERROR_NOT_IMPLEMENTED; }
+
+NS_IMETHODIMP
+imgRequestProxy::GetStatus(nsresult* aStatus) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP imgRequestProxy::SetCanceledReason(const nsACString& aReason) {
+ return SetCanceledReasonImpl(aReason);
+}
+
+NS_IMETHODIMP imgRequestProxy::GetCanceledReason(nsACString& aReason) {
+ return GetCanceledReasonImpl(aReason);
+}
+
+NS_IMETHODIMP imgRequestProxy::CancelWithReason(nsresult aStatus,
+ const nsACString& aReason) {
+ return CancelWithReasonImpl(aStatus, aReason);
+}
+
+void imgRequestProxy::SetCancelable(bool aCancelable) {
+ MOZ_ASSERT(NS_IsMainThread());
+ mCancelable = aCancelable;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::Cancel(nsresult status) {
+ if (mCanceled) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (NS_WARN_IF(!mCancelable)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ LOG_SCOPE(gImgLog, "imgRequestProxy::Cancel");
+
+ mCanceled = true;
+
+ nsCOMPtr<nsIRunnable> ev = new imgCancelRunnable(this, status);
+ return DispatchWithTargetIfAvailable(ev.forget());
+}
+
+void imgRequestProxy::DoCancel(nsresult status) {
+ RemoveFromOwner(status);
+ RemoveFromLoadGroup();
+ NullOutListener();
+}
+
+NS_IMETHODIMP
+imgRequestProxy::CancelAndForgetObserver(nsresult aStatus) {
+ // If mCanceled is true but mListener is non-null, that means
+ // someone called Cancel() on us but the imgCancelRunnable is still
+ // pending. We still need to null out mListener before returning
+ // from this function in this case. That means we want to do the
+ // RemoveProxy call right now, because we need to deliver the
+ // onStopRequest.
+ if (mCanceled && !mListener) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (NS_WARN_IF(!mCancelable)) {
+ MOZ_ASSERT(mCancelable,
+ "Shouldn't try to cancel non-cancelable requests via "
+ "CancelAndForgetObserver");
+ return NS_ERROR_FAILURE;
+ }
+
+ LOG_SCOPE(gImgLog, "imgRequestProxy::CancelAndForgetObserver");
+
+ mCanceled = true;
+ mForceDispatchLoadGroup = true;
+ RemoveFromOwner(aStatus);
+ RemoveFromLoadGroup();
+ mForceDispatchLoadGroup = false;
+
+ NullOutListener();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::StartDecoding(uint32_t aFlags) {
+ // Flag this, so we know to request after validation if pending.
+ if (IsValidating()) {
+ mDecodeRequested = true;
+ return NS_OK;
+ }
+
+ RefPtr<Image> image = GetImage();
+ if (image) {
+ return image->StartDecoding(aFlags);
+ }
+
+ if (GetOwner()) {
+ GetOwner()->StartDecoding();
+ }
+
+ return NS_OK;
+}
+
+bool imgRequestProxy::StartDecodingWithResult(uint32_t aFlags) {
+ // Flag this, so we know to request after validation if pending.
+ if (IsValidating()) {
+ mDecodeRequested = true;
+ return false;
+ }
+
+ RefPtr<Image> image = GetImage();
+ if (image) {
+ return image->StartDecodingWithResult(aFlags);
+ }
+
+ if (GetOwner()) {
+ GetOwner()->StartDecoding();
+ }
+
+ return false;
+}
+
+imgIContainer::DecodeResult imgRequestProxy::RequestDecodeWithResult(
+ uint32_t aFlags) {
+ if (IsValidating()) {
+ mDecodeRequested = true;
+ return imgIContainer::DECODE_REQUESTED;
+ }
+
+ RefPtr<Image> image = GetImage();
+ if (image) {
+ return image->RequestDecodeWithResult(aFlags);
+ }
+
+ if (GetOwner()) {
+ GetOwner()->StartDecoding();
+ }
+
+ return imgIContainer::DECODE_REQUESTED;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::LockImage() {
+ mLockCount++;
+ RefPtr<Image> image =
+ GetOwner() && GetOwner()->ImageAvailable() ? GetImage() : nullptr;
+ if (image) {
+ return image->LockImage();
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::UnlockImage() {
+ MOZ_ASSERT(mLockCount > 0, "calling unlock but no locks!");
+
+ mLockCount--;
+ RefPtr<Image> image =
+ GetOwner() && GetOwner()->ImageAvailable() ? GetImage() : nullptr;
+ if (image) {
+ return image->UnlockImage();
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::RequestDiscard() {
+ RefPtr<Image> image = GetImage();
+ if (image) {
+ return image->RequestDiscard();
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::IncrementAnimationConsumers() {
+ mAnimationConsumers++;
+ RefPtr<Image> image =
+ GetOwner() && GetOwner()->ImageAvailable() ? GetImage() : nullptr;
+ if (image) {
+ image->IncrementAnimationConsumers();
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::DecrementAnimationConsumers() {
+ // We may get here if some responsible code called Increment,
+ // then called us, but we have meanwhile called ClearAnimationConsumers
+ // because we needed to get rid of them earlier (see
+ // imgRequest::RemoveProxy), and hence have nothing left to
+ // decrement. (In such a case we got rid of the animation consumers
+ // early, but not the observer.)
+ if (mAnimationConsumers > 0) {
+ mAnimationConsumers--;
+ RefPtr<Image> image =
+ GetOwner() && GetOwner()->ImageAvailable() ? GetImage() : nullptr;
+ if (image) {
+ image->DecrementAnimationConsumers();
+ }
+ }
+ return NS_OK;
+}
+
+void imgRequestProxy::ClearAnimationConsumers() {
+ while (mAnimationConsumers > 0) {
+ DecrementAnimationConsumers();
+ }
+}
+
+NS_IMETHODIMP
+imgRequestProxy::Suspend() { return NS_ERROR_NOT_IMPLEMENTED; }
+
+NS_IMETHODIMP
+imgRequestProxy::Resume() { return NS_ERROR_NOT_IMPLEMENTED; }
+
+NS_IMETHODIMP
+imgRequestProxy::GetLoadGroup(nsILoadGroup** loadGroup) {
+ NS_IF_ADDREF(*loadGroup = mLoadGroup.get());
+ return NS_OK;
+}
+NS_IMETHODIMP
+imgRequestProxy::SetLoadGroup(nsILoadGroup* loadGroup) {
+ if (loadGroup != mLoadGroup) {
+ MOZ_ASSERT_UNREACHABLE("Switching load groups is unsupported!");
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetLoadFlags(nsLoadFlags* flags) {
+ *flags = mLoadFlags;
+ return NS_OK;
+}
+NS_IMETHODIMP
+imgRequestProxy::SetLoadFlags(nsLoadFlags flags) {
+ mLoadFlags = flags;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
+ return GetTRRModeImpl(aTRRMode);
+}
+
+NS_IMETHODIMP
+imgRequestProxy::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
+ return SetTRRModeImpl(aTRRMode);
+}
+
+/** imgIRequest methods **/
+
+NS_IMETHODIMP
+imgRequestProxy::GetImage(imgIContainer** aImage) {
+ NS_ENSURE_TRUE(aImage, NS_ERROR_NULL_POINTER);
+ // It's possible that our owner has an image but hasn't notified us of it -
+ // that'll happen if we get Canceled before the owner instantiates its image
+ // (because Canceling unregisters us as a listener on mOwner). If we're
+ // in that situation, just grab the image off of mOwner.
+ RefPtr<Image> image = GetImage();
+ nsCOMPtr<imgIContainer> imageToReturn;
+ if (image) {
+ imageToReturn = image;
+ }
+ if (!imageToReturn && GetOwner()) {
+ imageToReturn = GetOwner()->GetImage();
+ }
+ if (!imageToReturn) {
+ return NS_ERROR_FAILURE;
+ }
+
+ imageToReturn.swap(*aImage);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetProviderId(uint32_t* aId) {
+ NS_ENSURE_TRUE(aId, NS_ERROR_NULL_POINTER);
+
+ nsCOMPtr<imgIContainer> image;
+ nsresult rv = GetImage(getter_AddRefs(image));
+ if (NS_SUCCEEDED(rv)) {
+ *aId = image->GetProviderId();
+ } else {
+ *aId = 0;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetImageStatus(uint32_t* aStatus) {
+ if (IsValidating()) {
+ // We are currently validating the image, and so our status could revert if
+ // we discard the cache. We should also be deferring notifications, such
+ // that the caller will be notified when validation completes. Rather than
+ // risk misleading the caller, return nothing.
+ *aStatus = imgIRequest::STATUS_NONE;
+ } else {
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ *aStatus = progressTracker->GetImageStatus();
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetImageErrorCode(nsresult* aStatus) {
+ if (!GetOwner()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ *aStatus = GetOwner()->GetImageErrorCode();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetURI(nsIURI** aURI) {
+ MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread to convert URI");
+ nsCOMPtr<nsIURI> uri = mURI;
+ uri.forget(aURI);
+ return NS_OK;
+}
+
+nsresult imgRequestProxy::GetFinalURI(nsIURI** aURI) {
+ if (!GetOwner()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return GetOwner()->GetFinalURI(aURI);
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetNotificationObserver(imgINotificationObserver** aObserver) {
+ *aObserver = mListener;
+ NS_IF_ADDREF(*aObserver);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetMimeType(char** aMimeType) {
+ if (!GetOwner()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ const char* type = GetOwner()->GetMimeType();
+ if (!type) {
+ return NS_ERROR_FAILURE;
+ }
+
+ *aMimeType = NS_xstrdup(type);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetFileName(nsACString& aFileName) {
+ if (!GetOwner()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ GetOwner()->GetFileName(aFileName);
+ return NS_OK;
+}
+
+imgRequestProxy* imgRequestProxy::NewClonedProxy() {
+ return new imgRequestProxy();
+}
+
+NS_IMETHODIMP
+imgRequestProxy::Clone(imgINotificationObserver* aObserver,
+ imgIRequest** aClone) {
+ nsresult result;
+ imgRequestProxy* proxy;
+ result = PerformClone(aObserver, nullptr, /* aSyncNotify */ true, &proxy);
+ *aClone = proxy;
+ return result;
+}
+
+nsresult imgRequestProxy::SyncClone(imgINotificationObserver* aObserver,
+ Document* aLoadingDocument,
+ imgRequestProxy** aClone) {
+ return PerformClone(aObserver, aLoadingDocument,
+ /* aSyncNotify */ true, aClone);
+}
+
+nsresult imgRequestProxy::Clone(imgINotificationObserver* aObserver,
+ Document* aLoadingDocument,
+ imgRequestProxy** aClone) {
+ return PerformClone(aObserver, aLoadingDocument,
+ /* aSyncNotify */ false, aClone);
+}
+
+nsresult imgRequestProxy::PerformClone(imgINotificationObserver* aObserver,
+ Document* aLoadingDocument,
+ bool aSyncNotify,
+ imgRequestProxy** aClone) {
+ MOZ_ASSERT(aClone, "Null out param");
+
+ LOG_SCOPE(gImgLog, "imgRequestProxy::Clone");
+
+ *aClone = nullptr;
+ RefPtr<imgRequestProxy> clone = NewClonedProxy();
+
+ nsCOMPtr<nsILoadGroup> loadGroup;
+ if (aLoadingDocument) {
+ loadGroup = aLoadingDocument->GetDocumentLoadGroup();
+ }
+
+ // It is important to call |SetLoadFlags()| before calling |Init()| because
+ // |Init()| adds the request to the loadgroup.
+ // When a request is added to a loadgroup, its load flags are merged
+ // with the load flags of the loadgroup.
+ // XXXldb That's not true anymore. Stuff from imgLoader adds the
+ // request to the loadgroup.
+ clone->SetLoadFlags(mLoadFlags);
+ nsresult rv = clone->Init(mBehaviour->GetOwner(), loadGroup, aLoadingDocument,
+ mURI, aObserver);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ // Assign to *aClone before calling Notify so that if the caller expects to
+ // only be notified for requests it's already holding pointers to it won't be
+ // surprised.
+ NS_ADDREF(*aClone = clone);
+
+ imgCacheValidator* validator = GetValidator();
+ if (validator) {
+ // Note that if we have a validator, we don't want to issue notifications at
+ // here because we want to defer until that completes. AddProxy will add us
+ // to the load group; we cannot avoid that in this case, because we don't
+ // know when the validation will complete, and if it will cause us to
+ // discard our cached state anyways. We are probably already blocked by the
+ // original LoadImage(WithChannel) request in any event.
+ clone->MarkValidating();
+ validator->AddProxy(clone);
+ } else {
+ // We only want to add the request to the load group of the owning document
+ // if it is still in progress. Some callers cannot handle a supurious load
+ // group removal (e.g. print preview) so we must be careful. On the other
+ // hand, if after cloning, the original request proxy is cancelled /
+ // destroyed, we need to ensure that any clones still block the load group
+ // if it is incomplete.
+ bool addToLoadGroup = mIsInLoadGroup;
+ if (!addToLoadGroup) {
+ RefPtr<ProgressTracker> tracker = clone->GetProgressTracker();
+ addToLoadGroup =
+ tracker && !(tracker->GetProgress() & FLAG_LOAD_COMPLETE);
+ }
+
+ if (addToLoadGroup) {
+ clone->AddToLoadGroup();
+ }
+
+ if (aSyncNotify) {
+ // This is wrong!!! We need to notify asynchronously, but there's code
+ // that assumes that we don't. This will be fixed in bug 580466. Note that
+ // if we have a validator, we won't issue notifications anyways because
+ // they are deferred, so there is no point in requesting.
+ clone->mForceDispatchLoadGroup = true;
+ clone->SyncNotifyListener();
+ clone->mForceDispatchLoadGroup = false;
+ } else {
+ // Without a validator, we can request asynchronous notifications
+ // immediately. If there was a validator, this would override the deferral
+ // and that would be incorrect.
+ clone->NotifyListener();
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetImagePrincipal(nsIPrincipal** aPrincipal) {
+ if (!GetOwner()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsCOMPtr<nsIPrincipal> principal = GetOwner()->GetPrincipal();
+ principal.forget(aPrincipal);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetHadCrossOriginRedirects(bool* aHadCrossOriginRedirects) {
+ *aHadCrossOriginRedirects = false;
+
+ nsCOMPtr<nsITimedChannel> timedChannel = TimedChannel();
+ if (timedChannel) {
+ bool allRedirectsSameOrigin = false;
+ *aHadCrossOriginRedirects =
+ NS_SUCCEEDED(
+ timedChannel->GetAllRedirectsSameOrigin(&allRedirectsSameOrigin)) &&
+ !allRedirectsSameOrigin;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetMultipart(bool* aMultipart) {
+ if (!GetOwner()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ *aMultipart = GetOwner()->GetMultipart();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetCORSMode(int32_t* aCorsMode) {
+ if (!GetOwner()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ *aCorsMode = GetOwner()->GetCORSMode();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetReferrerInfo(nsIReferrerInfo** aReferrerInfo) {
+ if (!GetOwner()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsCOMPtr<nsIReferrerInfo> referrerInfo = GetOwner()->GetReferrerInfo();
+ referrerInfo.forget(aReferrerInfo);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::BoostPriority(uint32_t aCategory) {
+ NS_ENSURE_STATE(GetOwner() && !mCanceled);
+ GetOwner()->BoostPriority(aCategory);
+ return NS_OK;
+}
+
+/** nsISupportsPriority methods **/
+
+NS_IMETHODIMP
+imgRequestProxy::GetPriority(int32_t* priority) {
+ NS_ENSURE_STATE(GetOwner());
+ *priority = GetOwner()->Priority();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::SetPriority(int32_t priority) {
+ NS_ENSURE_STATE(GetOwner() && !mCanceled);
+ GetOwner()->AdjustPriority(this, priority - GetOwner()->Priority());
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxy::AdjustPriority(int32_t priority) {
+ // We don't require |!mCanceled| here. This may be called even if we're
+ // cancelled, because it's invoked as part of the process of removing an image
+ // from the load group.
+ NS_ENSURE_STATE(GetOwner());
+ GetOwner()->AdjustPriority(this, priority);
+ return NS_OK;
+}
+
+static const char* NotificationTypeToString(int32_t aType) {
+ switch (aType) {
+ case imgINotificationObserver::SIZE_AVAILABLE:
+ return "SIZE_AVAILABLE";
+ case imgINotificationObserver::FRAME_UPDATE:
+ return "FRAME_UPDATE";
+ case imgINotificationObserver::FRAME_COMPLETE:
+ return "FRAME_COMPLETE";
+ case imgINotificationObserver::LOAD_COMPLETE:
+ return "LOAD_COMPLETE";
+ case imgINotificationObserver::DECODE_COMPLETE:
+ return "DECODE_COMPLETE";
+ case imgINotificationObserver::DISCARD:
+ return "DISCARD";
+ case imgINotificationObserver::UNLOCKED_DRAW:
+ return "UNLOCKED_DRAW";
+ case imgINotificationObserver::IS_ANIMATED:
+ return "IS_ANIMATED";
+ case imgINotificationObserver::HAS_TRANSPARENCY:
+ return "HAS_TRANSPARENCY";
+ default:
+ MOZ_ASSERT_UNREACHABLE("Notification list should be exhaustive");
+ return "(unknown notification)";
+ }
+}
+
+void imgRequestProxy::Notify(int32_t aType,
+ const mozilla::gfx::IntRect* aRect) {
+ MOZ_ASSERT(aType != imgINotificationObserver::LOAD_COMPLETE,
+ "Should call OnLoadComplete");
+
+ LOG_FUNC_WITH_PARAM(gImgLog, "imgRequestProxy::Notify", "type",
+ NotificationTypeToString(aType));
+
+ if (!mListener || mCanceled) {
+ return;
+ }
+
+ // Make sure the listener stays alive while we notify.
+ nsCOMPtr<imgINotificationObserver> listener(mListener);
+
+ listener->Notify(this, aType, aRect);
+}
+
+void imgRequestProxy::OnLoadComplete(bool aLastPart) {
+ LOG_FUNC_WITH_PARAM(gImgLog, "imgRequestProxy::OnLoadComplete", "uri", mURI);
+
+ // There's all sorts of stuff here that could kill us (the OnStopRequest call
+ // on the listener, the removal from the loadgroup, the release of the
+ // listener, etc). Don't let them do it.
+ RefPtr<imgRequestProxy> self(this);
+
+ if (mListener && !mCanceled) {
+ // Hold a ref to the listener while we call it, just in case.
+ nsCOMPtr<imgINotificationObserver> listener(mListener);
+ listener->Notify(this, imgINotificationObserver::LOAD_COMPLETE, nullptr);
+ }
+
+ // If we're expecting more data from a multipart channel, re-add ourself
+ // to the loadgroup so that the document doesn't lose track of the load.
+ // If the request is already a background request and there's more data
+ // coming, we can just leave the request in the loadgroup as-is.
+ if (aLastPart || (mLoadFlags & nsIRequest::LOAD_BACKGROUND) == 0) {
+ if (aLastPart) {
+ RemoveFromLoadGroup();
+
+ nsresult errorCode = NS_OK;
+ // if the load is cross origin without CORS, or the CORS access is
+ // rejected, always fire load event to avoid leaking site information for
+ // <link rel=preload>.
+ // XXXedgar, currently we don't do the same thing for <img>.
+ imgRequest* request = GetOwner();
+ if (!request || !(request->IsDeniedCrossSiteCORSRequest() ||
+ request->IsCrossSiteNoCORSRequest())) {
+ uint32_t status = imgIRequest::STATUS_NONE;
+ GetImageStatus(&status);
+ if (status & imgIRequest::STATUS_ERROR) {
+ errorCode = NS_ERROR_FAILURE;
+ }
+ }
+ NotifyStop(errorCode);
+ } else {
+ // More data is coming, so change the request to be a background request
+ // and put it back in the loadgroup.
+ MoveToBackgroundInLoadGroup();
+ }
+ }
+
+ if (mListenerIsStrongRef && aLastPart) {
+ MOZ_ASSERT(mListener, "How did that happen?");
+ // Drop our strong ref to the listener now that we're done with
+ // everything. Note that this can cancel us and other fun things
+ // like that. Don't add anything in this method after this point.
+ imgINotificationObserver* obs = mListener;
+ mListenerIsStrongRef = false;
+ NS_RELEASE(obs);
+ }
+}
+
+void imgRequestProxy::NullOutListener() {
+ // If we have animation consumers, then they don't matter anymore
+ if (mListener) {
+ ClearAnimationConsumers();
+ }
+
+ if (mListenerIsStrongRef) {
+ // Releasing could do weird reentery stuff, so just play it super-safe
+ nsCOMPtr<imgINotificationObserver> obs;
+ obs.swap(mListener);
+ mListenerIsStrongRef = false;
+ } else {
+ mListener = nullptr;
+ }
+}
+
+NS_IMETHODIMP
+imgRequestProxy::GetStaticRequest(imgIRequest** aReturn) {
+ RefPtr<imgRequestProxy> proxy =
+ GetStaticRequest(static_cast<Document*>(nullptr));
+ if (proxy != this) {
+ RefPtr<Image> image = GetImage();
+ if (image && image->HasError()) {
+ // image/test/unit/test_async_notification_404.js needs this, but ideally
+ // this special case can be removed from the scripted codepath.
+ return NS_ERROR_FAILURE;
+ }
+ }
+ proxy.forget(aReturn);
+ return NS_OK;
+}
+
+already_AddRefed<imgRequestProxy> imgRequestProxy::GetStaticRequest(
+ Document* aLoadingDocument) {
+ MOZ_DIAGNOSTIC_ASSERT(!aLoadingDocument ||
+ aLoadingDocument->IsStaticDocument());
+ RefPtr<Image> image = GetImage();
+
+ bool animated;
+ if (!image || (NS_SUCCEEDED(image->GetAnimated(&animated)) && !animated)) {
+ // Early exit - we're not animated, so we don't have to do anything.
+ return do_AddRef(this);
+ }
+
+ // We are animated. We need to create a frozen version of this image.
+ RefPtr<Image> frozenImage = ImageOps::Freeze(image);
+
+ // Create a static imgRequestProxy with our new extracted frame.
+ nsCOMPtr<nsIPrincipal> currentPrincipal;
+ GetImagePrincipal(getter_AddRefs(currentPrincipal));
+ bool hadCrossOriginRedirects = true;
+ GetHadCrossOriginRedirects(&hadCrossOriginRedirects);
+ nsCOMPtr<nsIPrincipal> triggeringPrincipal = GetTriggeringPrincipal();
+ RefPtr<imgRequestProxy> req =
+ new imgRequestProxyStatic(frozenImage, currentPrincipal,
+ triggeringPrincipal, hadCrossOriginRedirects);
+ req->Init(nullptr, nullptr, aLoadingDocument, mURI, nullptr);
+
+ return req.forget();
+}
+
+void imgRequestProxy::NotifyListener() {
+ // It would be nice to notify the observer directly in the status tracker
+ // instead of through the proxy, but there are several places we do extra
+ // processing when we receive notifications (like OnStopRequest()), and we
+ // need to check mCanceled everywhere too.
+
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ if (GetOwner()) {
+ // Send the notifications to our listener asynchronously.
+ progressTracker->Notify(this);
+ } else {
+ // We don't have an imgRequest, so we can only notify the clone of our
+ // current state, but we still have to do that asynchronously.
+ MOZ_ASSERT(HasImage(), "if we have no imgRequest, we should have an Image");
+ progressTracker->NotifyCurrentState(this);
+ }
+}
+
+void imgRequestProxy::SyncNotifyListener() {
+ // It would be nice to notify the observer directly in the status tracker
+ // instead of through the proxy, but there are several places we do extra
+ // processing when we receive notifications (like OnStopRequest()), and we
+ // need to check mCanceled everywhere too.
+
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ progressTracker->SyncNotify(this);
+}
+
+void imgRequestProxy::SetHasImage() {
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ MOZ_ASSERT(progressTracker);
+ RefPtr<Image> image = progressTracker->GetImage();
+ MOZ_ASSERT(image);
+
+ // Force any private status related to the owner to reflect
+ // the presence of an image;
+ mBehaviour->SetOwner(mBehaviour->GetOwner());
+
+ // Apply any locks we have
+ for (uint32_t i = 0; i < mLockCount; ++i) {
+ image->LockImage();
+ }
+
+ // Apply any animation consumers we have
+ for (uint32_t i = 0; i < mAnimationConsumers; i++) {
+ image->IncrementAnimationConsumers();
+ }
+}
+
+already_AddRefed<ProgressTracker> imgRequestProxy::GetProgressTracker() const {
+ return mBehaviour->GetProgressTracker();
+}
+
+already_AddRefed<mozilla::image::Image> imgRequestProxy::GetImage() const {
+ return mBehaviour->GetImage();
+}
+
+bool RequestBehaviour::HasImage() const {
+ if (!mOwnerHasImage) {
+ return false;
+ }
+ RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
+ return progressTracker ? progressTracker->HasImage() : false;
+}
+
+bool imgRequestProxy::HasImage() const { return mBehaviour->HasImage(); }
+
+imgRequest* imgRequestProxy::GetOwner() const { return mBehaviour->GetOwner(); }
+
+imgCacheValidator* imgRequestProxy::GetValidator() const {
+ imgRequest* owner = GetOwner();
+ if (!owner) {
+ return nullptr;
+ }
+ return owner->GetValidator();
+}
+
+nsITimedChannel* imgRequestProxy::TimedChannel() {
+ if (!GetOwner()) {
+ return nullptr;
+ }
+ return GetOwner()->GetTimedChannel();
+}
+
+////////////////// imgRequestProxyStatic methods
+
+class StaticBehaviour : public ProxyBehaviour {
+ public:
+ explicit StaticBehaviour(mozilla::image::Image* aImage) : mImage(aImage) {}
+
+ already_AddRefed<mozilla::image::Image> GetImage() const override {
+ RefPtr<mozilla::image::Image> image = mImage;
+ return image.forget();
+ }
+
+ bool HasImage() const override { return mImage; }
+
+ already_AddRefed<ProgressTracker> GetProgressTracker() const override {
+ return mImage->GetProgressTracker();
+ }
+
+ imgRequest* GetOwner() const override { return nullptr; }
+
+ void SetOwner(imgRequest* aOwner) override {
+ MOZ_ASSERT(!aOwner,
+ "We shouldn't be giving static requests a non-null owner.");
+ }
+
+ private:
+ // Our image. We have to hold a strong reference here, because that's normally
+ // the job of the underlying request.
+ RefPtr<mozilla::image::Image> mImage;
+};
+
+imgRequestProxyStatic::imgRequestProxyStatic(mozilla::image::Image* aImage,
+ nsIPrincipal* aImagePrincipal,
+ nsIPrincipal* aTriggeringPrincipal,
+ bool aHadCrossOriginRedirects)
+ : mImagePrincipal(aImagePrincipal),
+ mTriggeringPrincipal(aTriggeringPrincipal),
+ mHadCrossOriginRedirects(aHadCrossOriginRedirects) {
+ mBehaviour = mozilla::MakeUnique<StaticBehaviour>(aImage);
+}
+
+NS_IMETHODIMP
+imgRequestProxyStatic::GetImagePrincipal(nsIPrincipal** aPrincipal) {
+ if (!mImagePrincipal) {
+ return NS_ERROR_FAILURE;
+ }
+ NS_ADDREF(*aPrincipal = mImagePrincipal);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxyStatic::GetTriggeringPrincipal(nsIPrincipal** aPrincipal) {
+ NS_IF_ADDREF(*aPrincipal = mTriggeringPrincipal);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgRequestProxyStatic::GetHadCrossOriginRedirects(
+ bool* aHadCrossOriginRedirects) {
+ *aHadCrossOriginRedirects = mHadCrossOriginRedirects;
+ return NS_OK;
+}
+
+imgRequestProxy* imgRequestProxyStatic::NewClonedProxy() {
+ nsCOMPtr<nsIPrincipal> currentPrincipal;
+ GetImagePrincipal(getter_AddRefs(currentPrincipal));
+ nsCOMPtr<nsIPrincipal> triggeringPrincipal;
+ GetTriggeringPrincipal(getter_AddRefs(triggeringPrincipal));
+ bool hadCrossOriginRedirects = true;
+ GetHadCrossOriginRedirects(&hadCrossOriginRedirects);
+ RefPtr<mozilla::image::Image> image = GetImage();
+ return new imgRequestProxyStatic(image, currentPrincipal, triggeringPrincipal,
+ hadCrossOriginRedirects);
+}
diff --git a/image/imgRequestProxy.h b/image/imgRequestProxy.h
new file mode 100644
index 0000000000..950c78341c
--- /dev/null
+++ b/image/imgRequestProxy.h
@@ -0,0 +1,263 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_imgRequestProxy_h
+#define mozilla_image_imgRequestProxy_h
+
+#include "imgIRequest.h"
+
+#include "nsIPrincipal.h"
+#include "nsISupportsPriority.h"
+#include "nsITimedChannel.h"
+#include "nsCOMPtr.h"
+#include "nsThreadUtils.h"
+#include "mozilla/PreloaderBase.h"
+#include "mozilla/TimeStamp.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/gfx/Rect.h"
+
+#include "IProgressObserver.h"
+
+#define NS_IMGREQUESTPROXY_CID \
+ { /* 20557898-1dd2-11b2-8f65-9c462ee2bc95 */ \
+ 0x20557898, 0x1dd2, 0x11b2, { \
+ 0x8f, 0x65, 0x9c, 0x46, 0x2e, 0xe2, 0xbc, 0x95 \
+ } \
+ }
+
+class imgCacheValidator;
+class imgINotificationObserver;
+class imgRequest;
+class imgStatusNotifyRunnable;
+class ProxyBehaviour;
+
+namespace mozilla {
+namespace image {
+class Image;
+class ProgressTracker;
+} // namespace image
+} // namespace mozilla
+
+class imgRequestProxy : public mozilla::PreloaderBase,
+ public imgIRequest,
+ public mozilla::image::IProgressObserver,
+ public nsISupportsPriority,
+ public nsITimedChannel {
+ protected:
+ virtual ~imgRequestProxy();
+
+ public:
+ typedef mozilla::dom::Document Document;
+ typedef mozilla::image::Image Image;
+ typedef mozilla::image::ProgressTracker ProgressTracker;
+
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMGREQUESTPROXY_CID)
+ MOZ_DECLARE_REFCOUNTED_TYPENAME(imgRequestProxy)
+ NS_DECL_ISUPPORTS
+ NS_DECL_IMGIREQUEST
+ NS_DECL_NSIREQUEST
+ NS_DECL_NSISUPPORTSPRIORITY
+ // nsITimedChannel declared below
+
+ imgRequestProxy();
+
+ // Callers to Init or ChangeOwner are required to call NotifyListener after
+ // (although not immediately after) doing so.
+ nsresult Init(imgRequest* aOwner, nsILoadGroup* aLoadGroup,
+ Document* aLoadingDocument, nsIURI* aURI,
+ imgINotificationObserver* aObserver);
+
+ nsresult ChangeOwner(imgRequest* aNewOwner); // this will change mOwner.
+ // Do not call this if the
+ // previous owner has already
+ // sent notifications out!
+
+ // Add the request to the load group, if any. This should only be called once
+ // during initialization.
+ void AddToLoadGroup();
+
+ inline bool HasObserver() const { return mListener != nullptr; }
+
+ // Asynchronously notify this proxy's listener of the current state of the
+ // image, and, if we have an imgRequest mOwner, any status changes that
+ // happen between the time this function is called and the time the
+ // notification is scheduled.
+ void NotifyListener();
+
+ // Synchronously notify this proxy's listener of the current state of the
+ // image. Only use this function if you are currently servicing an
+ // asynchronously-called function.
+ void SyncNotifyListener();
+
+ // imgINotificationObserver methods:
+ virtual void Notify(int32_t aType,
+ const mozilla::gfx::IntRect* aRect = nullptr) override;
+ virtual void OnLoadComplete(bool aLastPart) override;
+
+ // Other, internal-only methods:
+ virtual void SetHasImage() override;
+
+ // Whether we want notifications from ProgressTracker to be deferred until
+ // an event it has scheduled has been fired and/or validation is complete.
+ virtual bool NotificationsDeferred() const override {
+ return IsValidating() || mPendingNotify;
+ }
+ virtual void MarkPendingNotify() override { mPendingNotify = true; }
+ virtual void ClearPendingNotify() override { mPendingNotify = false; }
+ bool IsValidating() const { return mValidating; }
+ void MarkValidating();
+ void ClearValidating();
+
+ // Flags this image load as not cancelable temporarily. This is needed so that
+ // stylesheets can be shared across documents properly, see bug 1800979.
+ void SetCancelable(bool);
+
+ already_AddRefed<nsIEventTarget> GetEventTarget() const override;
+
+ // Removes all animation consumers that were created with
+ // IncrementAnimationConsumers. This is necessary since we need
+ // to do it before the proxy itself is destroyed. See
+ // imgRequest::RemoveProxy
+ void ClearAnimationConsumers();
+
+ nsresult SyncClone(imgINotificationObserver* aObserver,
+ Document* aLoadingDocument, imgRequestProxy** aClone);
+ nsresult Clone(imgINotificationObserver* aObserver,
+ Document* aLoadingDocument, imgRequestProxy** aClone);
+ already_AddRefed<imgRequestProxy> GetStaticRequest(
+ Document* aLoadingDocument);
+
+ imgRequest* GetOwner() const;
+
+ // PreloaderBase
+ // We are using the default image loader prioritization for preloads.
+ virtual void PrioritizeAsPreload() override {}
+
+ protected:
+ friend class mozilla::image::ProgressTracker;
+ friend class imgStatusNotifyRunnable;
+
+ class imgCancelRunnable;
+ friend class imgCancelRunnable;
+
+ class imgCancelRunnable : public mozilla::Runnable {
+ public:
+ imgCancelRunnable(imgRequestProxy* owner, nsresult status)
+ : Runnable("imgCancelRunnable"), mOwner(owner), mStatus(status) {}
+
+ NS_IMETHOD Run() override {
+ mOwner->DoCancel(mStatus);
+ return NS_OK;
+ }
+
+ private:
+ RefPtr<imgRequestProxy> mOwner;
+ nsresult mStatus;
+ };
+
+ /* Remove from and forget the load group. */
+ void RemoveFromLoadGroup();
+
+ /* Remove from the load group and re-add as a background request. */
+ void MoveToBackgroundInLoadGroup();
+
+ /* Finish up canceling ourselves */
+ void DoCancel(nsresult status);
+
+ /* Do the proper refcount management to null out mListener */
+ void NullOutListener();
+
+ // Return the ProgressTracker associated with mOwner and/or mImage. It may
+ // live either on mOwner or mImage, depending on whether
+ // (a) we have an mOwner at all
+ // (b) whether mOwner has instantiated its image yet
+ already_AddRefed<ProgressTracker> GetProgressTracker() const;
+
+ nsITimedChannel* TimedChannel();
+
+ already_AddRefed<Image> GetImage() const;
+ bool HasImage() const;
+ imgCacheValidator* GetValidator() const;
+
+ nsresult PerformClone(imgINotificationObserver* aObserver,
+ Document* aLoadingDocument, bool aSyncNotify,
+ imgRequestProxy** aClone);
+
+ virtual imgRequestProxy* NewClonedProxy();
+
+ public:
+ NS_FORWARD_SAFE_NSITIMEDCHANNEL(TimedChannel())
+
+ protected:
+ mozilla::UniquePtr<ProxyBehaviour> mBehaviour;
+
+ private:
+ friend class imgCacheValidator;
+
+ void AddToOwner(Document* aLoadingDocument);
+ void RemoveFromOwner(nsresult aStatus);
+
+ nsresult DispatchWithTargetIfAvailable(already_AddRefed<nsIRunnable> aEvent);
+
+ // The URI of our request.
+ nsCOMPtr<nsIURI> mURI;
+
+ // mListener is only promised to be a weak ref (see imgILoader.idl),
+ // but we actually keep a strong ref to it until we've seen our
+ // first OnStopRequest.
+ imgINotificationObserver* MOZ_UNSAFE_REF(
+ "Observers must call Cancel() or "
+ "CancelAndForgetObserver() before "
+ "they are destroyed") mListener;
+
+ nsCOMPtr<nsILoadGroup> mLoadGroup;
+ nsCOMPtr<nsIEventTarget> mEventTarget;
+
+ nsLoadFlags mLoadFlags;
+ uint32_t mLockCount;
+ uint32_t mAnimationConsumers;
+ bool mCancelable : 1;
+ bool mCanceled : 1;
+ bool mIsInLoadGroup : 1;
+ bool mForceDispatchLoadGroup : 1;
+ bool mListenerIsStrongRef : 1;
+ bool mDecodeRequested : 1;
+
+ // Whether we want to defer our notifications by the non-virtual Observer
+ // interfaces as image loads proceed.
+ bool mPendingNotify : 1;
+ bool mValidating : 1;
+ bool mHadListener : 1;
+ bool mHadDispatch : 1;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(imgRequestProxy, NS_IMGREQUESTPROXY_CID)
+
+// Used for static image proxies for which no requests are available, so
+// certain behaviours must be overridden to compensate.
+class imgRequestProxyStatic : public imgRequestProxy {
+ public:
+ imgRequestProxyStatic(Image* aImage, nsIPrincipal* aImagePrincipal,
+ nsIPrincipal* aTriggeringPrincipal,
+ bool hadCrossOriginRedirects);
+
+ NS_IMETHOD GetImagePrincipal(nsIPrincipal** aPrincipal) override;
+ NS_IMETHOD GetTriggeringPrincipal(nsIPrincipal** aPrincipal) override;
+
+ NS_IMETHOD GetHadCrossOriginRedirects(
+ bool* aHadCrossOriginRedirects) override;
+
+ protected:
+ imgRequestProxy* NewClonedProxy() override;
+
+ // Our principal. We have to cache it, rather than accessing the underlying
+ // request on-demand, because static proxies don't have an underlying request.
+ const nsCOMPtr<nsIPrincipal> mImagePrincipal;
+ const nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
+ const bool mHadCrossOriginRedirects;
+};
+
+#endif // mozilla_image_imgRequestProxy_h
diff --git a/image/imgTools.cpp b/image/imgTools.cpp
new file mode 100644
index 0000000000..864efc6f44
--- /dev/null
+++ b/image/imgTools.cpp
@@ -0,0 +1,649 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "imgTools.h"
+
+#include "DecodePool.h"
+#include "gfxUtils.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Logging.h"
+#include "mozilla/RefPtr.h"
+#include "nsCOMPtr.h"
+#include "mozilla/dom/Document.h"
+#include "nsError.h"
+#include "imgLoader.h"
+#include "imgICache.h"
+#include "imgIContainer.h"
+#include "imgIEncoder.h"
+#include "nsComponentManagerUtils.h"
+#include "nsNetUtil.h" // for NS_NewBufferedInputStream
+#include "nsStreamUtils.h"
+#include "nsStringStream.h"
+#include "nsContentUtils.h"
+#include "nsProxyRelease.h"
+#include "nsIStreamListener.h"
+#include "ImageFactory.h"
+#include "Image.h"
+#include "IProgressObserver.h"
+#include "ScriptedNotificationObserver.h"
+#include "imgIScriptedNotificationObserver.h"
+#include "gfxPlatform.h"
+#include "js/ArrayBuffer.h"
+#include "js/RootingAPI.h" // JS::{Handle,Rooted}
+#include "js/Value.h" // JS::Value
+#include "Orientation.h"
+
+using namespace mozilla::gfx;
+
+namespace mozilla {
+namespace image {
+
+namespace {
+
+static nsresult sniff_mimetype_callback(nsIInputStream* in, void* data,
+ const char* fromRawSegment,
+ uint32_t toOffset, uint32_t count,
+ uint32_t* writeCount) {
+ nsCString* mimeType = static_cast<nsCString*>(data);
+ MOZ_ASSERT(mimeType, "mimeType is null!");
+
+ if (count > 0) {
+ imgLoader::GetMimeTypeFromContent(fromRawSegment, count, *mimeType);
+ }
+
+ *writeCount = 0;
+ return NS_ERROR_FAILURE;
+}
+
+class ImageDecoderListener final : public nsIStreamListener,
+ public IProgressObserver,
+ public imgIContainer {
+ public:
+ NS_DECL_ISUPPORTS
+
+ ImageDecoderListener(nsIURI* aURI, imgIContainerCallback* aCallback,
+ imgINotificationObserver* aObserver)
+ : mURI(aURI),
+ mImage(nullptr),
+ mCallback(aCallback),
+ mObserver(aObserver) {
+ MOZ_ASSERT(NS_IsMainThread());
+ }
+
+ NS_IMETHOD
+ OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream,
+ uint64_t aOffset, uint32_t aCount) override {
+ if (!mImage) {
+ nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
+
+ nsCString mimeType;
+ channel->GetContentType(mimeType);
+
+ if (aInputStream) {
+ // Look at the first few bytes and see if we can tell what the data is
+ // from that since servers tend to lie. :(
+ uint32_t unused;
+ aInputStream->ReadSegments(sniff_mimetype_callback, &mimeType, aCount,
+ &unused);
+ }
+
+ RefPtr<ProgressTracker> tracker = new ProgressTracker();
+ if (mObserver) {
+ tracker->AddObserver(this);
+ }
+
+ mImage = ImageFactory::CreateImage(channel, tracker, mimeType, mURI,
+ /* aIsMultiPart */ false, 0);
+
+ if (mImage->HasError()) {
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ return mImage->OnImageDataAvailable(aRequest, aInputStream, aOffset,
+ aCount);
+ }
+
+ NS_IMETHOD
+ OnStartRequest(nsIRequest* aRequest) override { return NS_OK; }
+
+ NS_IMETHOD
+ OnStopRequest(nsIRequest* aRequest, nsresult aStatus) override {
+ // Encouter a fetch error, or no data could be fetched.
+ if (!mImage || NS_FAILED(aStatus)) {
+ mCallback->OnImageReady(nullptr, mImage ? aStatus : NS_ERROR_FAILURE);
+ return NS_OK;
+ }
+
+ mImage->OnImageDataComplete(aRequest, aStatus, true);
+ nsCOMPtr<imgIContainer> container = this;
+ mCallback->OnImageReady(container, aStatus);
+ return NS_OK;
+ }
+
+ virtual void Notify(int32_t aType,
+ const nsIntRect* aRect = nullptr) override {
+ if (mObserver) {
+ mObserver->Notify(nullptr, aType, aRect);
+ }
+ }
+
+ virtual void OnLoadComplete(bool aLastPart) override {}
+
+ // Other notifications are ignored.
+ virtual void SetHasImage() override {}
+ virtual bool NotificationsDeferred() const override { return false; }
+ virtual void MarkPendingNotify() override {}
+ virtual void ClearPendingNotify() override {}
+
+ // imgIContainer
+ NS_FORWARD_IMGICONTAINER(mImage->)
+
+ private:
+ virtual ~ImageDecoderListener() = default;
+
+ nsCOMPtr<nsIURI> mURI;
+ RefPtr<image::Image> mImage;
+ nsCOMPtr<imgIContainerCallback> mCallback;
+ nsCOMPtr<imgINotificationObserver> mObserver;
+};
+
+NS_IMPL_ISUPPORTS(ImageDecoderListener, nsIStreamListener, imgIContainer)
+
+class ImageDecoderHelper final : public Runnable,
+ public nsIInputStreamCallback {
+ public:
+ NS_DECL_ISUPPORTS_INHERITED
+
+ ImageDecoderHelper(already_AddRefed<image::Image> aImage,
+ already_AddRefed<nsIInputStream> aInputStream,
+ nsIEventTarget* aEventTarget,
+ imgIContainerCallback* aCallback,
+ nsIEventTarget* aCallbackEventTarget)
+ : Runnable("ImageDecoderHelper"),
+ mImage(std::move(aImage)),
+ mInputStream(std::move(aInputStream)),
+ mEventTarget(aEventTarget),
+ mCallback(aCallback),
+ mCallbackEventTarget(aCallbackEventTarget),
+ mStatus(NS_OK) {
+ MOZ_ASSERT(NS_IsMainThread());
+ }
+
+ NS_IMETHOD
+ Run() override {
+ // This runnable is dispatched on the Image thread when reading data, but
+ // at the end, it goes back to the main-thread in order to complete the
+ // operation.
+ if (NS_IsMainThread()) {
+ // Let the Image know we've sent all the data.
+ mImage->OnImageDataComplete(nullptr, mStatus, true);
+
+ RefPtr<ProgressTracker> tracker = mImage->GetProgressTracker();
+ tracker->SyncNotifyProgress(FLAG_LOAD_COMPLETE);
+
+ nsCOMPtr<imgIContainer> container;
+ if (NS_SUCCEEDED(mStatus)) {
+ container = mImage;
+ }
+
+ mCallback->OnImageReady(container, mStatus);
+ return NS_OK;
+ }
+
+ uint64_t length;
+ nsresult rv = mInputStream->Available(&length);
+ if (rv == NS_BASE_STREAM_CLOSED) {
+ return OperationCompleted(NS_OK);
+ }
+
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return OperationCompleted(rv);
+ }
+
+ // Nothing else to read, but maybe we just need to wait.
+ if (length == 0) {
+ nsCOMPtr<nsIAsyncInputStream> asyncInputStream =
+ do_QueryInterface(mInputStream);
+ if (asyncInputStream) {
+ rv = asyncInputStream->AsyncWait(this, 0, 0, mEventTarget);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return OperationCompleted(rv);
+ }
+ return NS_OK;
+ }
+
+ // We really have nothing else to read.
+ if (length == 0) {
+ return OperationCompleted(NS_OK);
+ }
+ }
+
+ // Send the source data to the Image.
+ rv = mImage->OnImageDataAvailable(nullptr, mInputStream, 0,
+ uint32_t(length));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return OperationCompleted(rv);
+ }
+
+ rv = mEventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return OperationCompleted(rv);
+ }
+
+ return NS_OK;
+ }
+
+ NS_IMETHOD
+ OnInputStreamReady(nsIAsyncInputStream* aAsyncInputStream) override {
+ MOZ_ASSERT(!NS_IsMainThread());
+ return Run();
+ }
+
+ nsresult OperationCompleted(nsresult aStatus) {
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ mStatus = aStatus;
+ mCallbackEventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
+ return NS_OK;
+ }
+
+ private:
+ ~ImageDecoderHelper() {
+ SurfaceCache::ReleaseImageOnMainThread(mImage.forget());
+ NS_ReleaseOnMainThread("ImageDecoderHelper::mCallback", mCallback.forget());
+ }
+
+ RefPtr<image::Image> mImage;
+
+ nsCOMPtr<nsIInputStream> mInputStream;
+ nsCOMPtr<nsIEventTarget> mEventTarget;
+ nsCOMPtr<imgIContainerCallback> mCallback;
+ nsCOMPtr<nsIEventTarget> mCallbackEventTarget;
+
+ nsresult mStatus;
+};
+
+NS_IMPL_ISUPPORTS_INHERITED(ImageDecoderHelper, Runnable,
+ nsIInputStreamCallback)
+
+} // namespace
+
+/* ========== imgITools implementation ========== */
+
+NS_IMPL_ISUPPORTS(imgTools, imgITools)
+
+imgTools::imgTools() { /* member initializers and constructor code */
+}
+
+imgTools::~imgTools() { /* destructor code */
+}
+
+NS_IMETHODIMP
+imgTools::DecodeImageFromArrayBuffer(JS::Handle<JS::Value> aArrayBuffer,
+ const nsACString& aMimeType,
+ JSContext* aCx,
+ imgIContainer** aContainer) {
+ if (!aArrayBuffer.isObject()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ JS::Rooted<JSObject*> obj(aCx,
+ JS::UnwrapArrayBuffer(&aArrayBuffer.toObject()));
+ if (!obj) {
+ return NS_ERROR_FAILURE;
+ }
+
+ uint8_t* bufferData = nullptr;
+ size_t bufferLength = 0;
+ bool isSharedMemory = false;
+
+ JS::GetArrayBufferLengthAndData(obj, &bufferLength, &isSharedMemory,
+ &bufferData);
+
+ // Throw for large ArrayBuffers to prevent truncation.
+ if (bufferLength > INT32_MAX) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ return DecodeImageFromBuffer((char*)bufferData, bufferLength, aMimeType,
+ aContainer);
+}
+
+NS_IMETHODIMP
+imgTools::DecodeImageFromBuffer(const char* aBuffer, uint32_t aSize,
+ const nsACString& aMimeType,
+ imgIContainer** aContainer) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ NS_ENSURE_ARG_POINTER(aBuffer);
+
+ // Create a new image container to hold the decoded data.
+ nsAutoCString mimeType(aMimeType);
+ RefPtr<image::Image> image =
+ ImageFactory::CreateAnonymousImage(mimeType, aSize);
+ RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
+
+ if (image->HasError()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Let's create a temporary inputStream.
+ nsCOMPtr<nsIInputStream> stream;
+ nsresult rv = NS_NewByteInputStream(
+ getter_AddRefs(stream), Span(aBuffer, aSize), NS_ASSIGNMENT_DEPEND);
+ NS_ENSURE_SUCCESS(rv, rv);
+ MOZ_ASSERT(stream);
+ MOZ_ASSERT(NS_InputStreamIsBuffered(stream));
+
+ rv = image->OnImageDataAvailable(nullptr, stream, 0, aSize);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Let the Image know we've sent all the data.
+ rv = image->OnImageDataComplete(nullptr, NS_OK, true);
+ tracker->SyncNotifyProgress(FLAG_LOAD_COMPLETE);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // All done.
+ image.forget(aContainer);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgTools::DecodeImageFromChannelAsync(nsIURI* aURI, nsIChannel* aChannel,
+ imgIContainerCallback* aCallback,
+ imgINotificationObserver* aObserver) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ NS_ENSURE_ARG_POINTER(aURI);
+ NS_ENSURE_ARG_POINTER(aChannel);
+ NS_ENSURE_ARG_POINTER(aCallback);
+
+ RefPtr<ImageDecoderListener> listener =
+ new ImageDecoderListener(aURI, aCallback, aObserver);
+
+ return aChannel->AsyncOpen(listener);
+}
+
+NS_IMETHODIMP
+imgTools::DecodeImageAsync(nsIInputStream* aInStr, const nsACString& aMimeType,
+ imgIContainerCallback* aCallback,
+ nsIEventTarget* aEventTarget) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ NS_ENSURE_ARG_POINTER(aInStr);
+ NS_ENSURE_ARG_POINTER(aCallback);
+ NS_ENSURE_ARG_POINTER(aEventTarget);
+
+ nsresult rv;
+
+ // Let's continuing the reading on a separate thread.
+ DecodePool* decodePool = DecodePool::Singleton();
+ MOZ_ASSERT(decodePool);
+
+ RefPtr<nsIEventTarget> target = decodePool->GetIOEventTarget();
+ NS_ENSURE_TRUE(target, NS_ERROR_FAILURE);
+
+ // Prepare the input stream.
+ nsCOMPtr<nsIInputStream> stream = aInStr;
+ if (!NS_InputStreamIsBuffered(aInStr)) {
+ nsCOMPtr<nsIInputStream> bufStream;
+ rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream), stream.forget(),
+ 1024);
+ NS_ENSURE_SUCCESS(rv, rv);
+ stream = std::move(bufStream);
+ }
+
+ // Create a new image container to hold the decoded data.
+ nsAutoCString mimeType(aMimeType);
+ RefPtr<image::Image> image = ImageFactory::CreateAnonymousImage(mimeType, 0);
+
+ // Already an error?
+ if (image->HasError()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ RefPtr<ImageDecoderHelper> helper = new ImageDecoderHelper(
+ image.forget(), stream.forget(), target, aCallback, aEventTarget);
+ rv = target->Dispatch(helper.forget(), NS_DISPATCH_NORMAL);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_OK;
+}
+
+/**
+ * This takes a DataSourceSurface rather than a SourceSurface because some
+ * of the callers have a DataSourceSurface and we don't want to call
+ * GetDataSurface on such surfaces since that may incur a conversion to
+ * SurfaceType::DATA which we don't need.
+ */
+static nsresult EncodeImageData(DataSourceSurface* aDataSurface,
+ DataSourceSurface::ScopedMap& aMap,
+ const nsACString& aMimeType,
+ const nsAString& aOutputOptions,
+ nsIInputStream** aStream) {
+ MOZ_ASSERT(aDataSurface->GetFormat() == SurfaceFormat::B8G8R8A8 ||
+ aDataSurface->GetFormat() == SurfaceFormat::B8G8R8X8,
+ "We're assuming B8G8R8A8/X8");
+
+ // Get an image encoder for the media type
+ nsAutoCString encoderCID("@mozilla.org/image/encoder;2?type="_ns + aMimeType);
+
+ nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(encoderCID.get());
+ if (!encoder) {
+ return NS_IMAGELIB_ERROR_NO_ENCODER;
+ }
+
+ IntSize size = aDataSurface->GetSize();
+ uint32_t dataLength = aMap.GetStride() * size.height;
+
+ // Encode the bitmap
+ nsresult rv = encoder->InitFromData(
+ aMap.GetData(), dataLength, size.width, size.height, aMap.GetStride(),
+ imgIEncoder::INPUT_FORMAT_HOSTARGB, aOutputOptions);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ encoder.forget(aStream);
+ return NS_OK;
+}
+
+static nsresult EncodeImageData(DataSourceSurface* aDataSurface,
+ const nsACString& aMimeType,
+ const nsAString& aOutputOptions,
+ nsIInputStream** aStream) {
+ DataSourceSurface::ScopedMap map(aDataSurface, DataSourceSurface::READ);
+ if (!map.IsMapped()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return EncodeImageData(aDataSurface, map, aMimeType, aOutputOptions, aStream);
+}
+
+NS_IMETHODIMP
+imgTools::EncodeImage(imgIContainer* aContainer, const nsACString& aMimeType,
+ const nsAString& aOutputOptions,
+ nsIInputStream** aStream) {
+ // Use frame 0 from the image container.
+ RefPtr<SourceSurface> frame = aContainer->GetFrame(
+ imgIContainer::FRAME_FIRST,
+ imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_ASYNC_NOTIFY);
+ NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
+
+ RefPtr<DataSourceSurface> dataSurface;
+
+ if (frame->GetFormat() == SurfaceFormat::B8G8R8A8 ||
+ frame->GetFormat() == SurfaceFormat::B8G8R8X8) {
+ dataSurface = frame->GetDataSurface();
+ } else {
+ // Convert format to SurfaceFormat::B8G8R8A8
+ dataSurface = gfxUtils::CopySurfaceToDataSourceSurfaceWithFormat(
+ frame, SurfaceFormat::B8G8R8A8);
+ }
+
+ NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
+
+ return EncodeImageData(dataSurface, aMimeType, aOutputOptions, aStream);
+}
+
+NS_IMETHODIMP
+imgTools::EncodeScaledImage(imgIContainer* aContainer,
+ const nsACString& aMimeType, int32_t aScaledWidth,
+ int32_t aScaledHeight,
+ const nsAString& aOutputOptions,
+ nsIInputStream** aStream) {
+ NS_ENSURE_ARG(aScaledWidth >= 0 && aScaledHeight >= 0);
+
+ // If no scaled size is specified, we'll just encode the image at its
+ // original size (no scaling).
+ if (aScaledWidth == 0 && aScaledHeight == 0) {
+ return EncodeImage(aContainer, aMimeType, aOutputOptions, aStream);
+ }
+
+ // Retrieve the image's size.
+ int32_t imageWidth = 0;
+ int32_t imageHeight = 0;
+ aContainer->GetWidth(&imageWidth);
+ aContainer->GetHeight(&imageHeight);
+
+ // If the given width or height is zero we'll replace it with the image's
+ // original dimensions.
+ IntSize scaledSize(aScaledWidth == 0 ? imageWidth : aScaledWidth,
+ aScaledHeight == 0 ? imageHeight : aScaledHeight);
+
+ // Use frame 0 from the image container.
+ RefPtr<SourceSurface> frame = aContainer->GetFrameAtSize(
+ scaledSize, imgIContainer::FRAME_FIRST,
+ imgIContainer::FLAG_HIGH_QUALITY_SCALING |
+ imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_ASYNC_NOTIFY);
+ NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
+
+ // If the given surface is the right size/format, we can encode it directly.
+ if (scaledSize == frame->GetSize() &&
+ (frame->GetFormat() == SurfaceFormat::B8G8R8A8 ||
+ frame->GetFormat() == SurfaceFormat::B8G8R8X8)) {
+ RefPtr<DataSourceSurface> dataSurface = frame->GetDataSurface();
+ if (dataSurface) {
+ return EncodeImageData(dataSurface, aMimeType, aOutputOptions, aStream);
+ }
+ }
+
+ // Otherwise we need to scale it using a draw target.
+ RefPtr<DataSourceSurface> dataSurface =
+ Factory::CreateDataSourceSurface(scaledSize, SurfaceFormat::B8G8R8A8);
+ if (NS_WARN_IF(!dataSurface)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ DataSourceSurface::ScopedMap map(dataSurface, DataSourceSurface::READ_WRITE);
+ if (!map.IsMapped()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ RefPtr<DrawTarget> dt = Factory::CreateDrawTargetForData(
+ BackendType::SKIA, map.GetData(), dataSurface->GetSize(), map.GetStride(),
+ SurfaceFormat::B8G8R8A8);
+ if (!dt) {
+ gfxWarning() << "imgTools::EncodeImage failed in CreateDrawTargetForData";
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ IntSize frameSize = frame->GetSize();
+ dt->DrawSurface(frame, Rect(0, 0, scaledSize.width, scaledSize.height),
+ Rect(0, 0, frameSize.width, frameSize.height),
+ DrawSurfaceOptions(),
+ DrawOptions(1.0f, CompositionOp::OP_SOURCE));
+
+ return EncodeImageData(dataSurface, map, aMimeType, aOutputOptions, aStream);
+}
+
+NS_IMETHODIMP
+imgTools::EncodeCroppedImage(imgIContainer* aContainer,
+ const nsACString& aMimeType, int32_t aOffsetX,
+ int32_t aOffsetY, int32_t aWidth, int32_t aHeight,
+ const nsAString& aOutputOptions,
+ nsIInputStream** aStream) {
+ NS_ENSURE_ARG(aOffsetX >= 0 && aOffsetY >= 0 && aWidth >= 0 && aHeight >= 0);
+
+ // Offsets must be zero when no width and height are given or else we're out
+ // of bounds.
+ NS_ENSURE_ARG(aWidth + aHeight > 0 || aOffsetX + aOffsetY == 0);
+
+ // If no size is specified then we'll preserve the image's original dimensions
+ // and don't need to crop.
+ if (aWidth == 0 && aHeight == 0) {
+ return EncodeImage(aContainer, aMimeType, aOutputOptions, aStream);
+ }
+
+ // Use frame 0 from the image container.
+ RefPtr<SourceSurface> frame = aContainer->GetFrame(
+ imgIContainer::FRAME_FIRST,
+ imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_ASYNC_NOTIFY);
+ NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
+
+ int32_t frameWidth = frame->GetSize().width;
+ int32_t frameHeight = frame->GetSize().height;
+
+ // If the given width or height is zero we'll replace it with the image's
+ // original dimensions.
+ if (aWidth == 0) {
+ aWidth = frameWidth;
+ } else if (aHeight == 0) {
+ aHeight = frameHeight;
+ }
+
+ // Check that the given crop rectangle is within image bounds.
+ NS_ENSURE_ARG(frameWidth >= aOffsetX + aWidth &&
+ frameHeight >= aOffsetY + aHeight);
+
+ RefPtr<DataSourceSurface> dataSurface = Factory::CreateDataSourceSurface(
+ IntSize(aWidth, aHeight), SurfaceFormat::B8G8R8A8,
+ /* aZero = */ true);
+ if (NS_WARN_IF(!dataSurface)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ DataSourceSurface::ScopedMap map(dataSurface, DataSourceSurface::READ_WRITE);
+ if (!map.IsMapped()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ RefPtr<DrawTarget> dt = Factory::CreateDrawTargetForData(
+ BackendType::SKIA, map.GetData(), dataSurface->GetSize(), map.GetStride(),
+ SurfaceFormat::B8G8R8A8);
+ if (!dt) {
+ gfxWarning()
+ << "imgTools::EncodeCroppedImage failed in CreateDrawTargetForData";
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ dt->CopySurface(frame, IntRect(aOffsetX, aOffsetY, aWidth, aHeight),
+ IntPoint(0, 0));
+
+ return EncodeImageData(dataSurface, map, aMimeType, aOutputOptions, aStream);
+}
+
+NS_IMETHODIMP
+imgTools::CreateScriptedObserver(imgIScriptedNotificationObserver* aInner,
+ imgINotificationObserver** aObserver) {
+ NS_ADDREF(*aObserver = new ScriptedNotificationObserver(aInner));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgTools::GetImgLoaderForDocument(dom::Document* aDoc, imgILoader** aLoader) {
+ NS_IF_ADDREF(*aLoader = nsContentUtils::GetImgLoaderForDocument(aDoc));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+imgTools::GetImgCacheForDocument(dom::Document* aDoc, imgICache** aCache) {
+ nsCOMPtr<imgILoader> loader;
+ nsresult rv = GetImgLoaderForDocument(aDoc, getter_AddRefs(loader));
+ NS_ENSURE_SUCCESS(rv, rv);
+ return CallQueryInterface(loader, aCache);
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/imgTools.h b/image/imgTools.h
new file mode 100644
index 0000000000..1075e1dbef
--- /dev/null
+++ b/image/imgTools.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_imgITools_h
+#define mozilla_image_imgITools_h
+
+#include "imgITools.h"
+
+#define NS_IMGTOOLS_CID \
+ { /* 3d8fa16d-c9e1-4b50-bdef-2c7ae249967a */ \
+ 0x3d8fa16d, 0xc9e1, 0x4b50, { \
+ 0xbd, 0xef, 0x2c, 0x7a, 0xe2, 0x49, 0x96, 0x7a \
+ } \
+ }
+
+namespace mozilla {
+namespace image {
+
+class imgTools final : public imgITools {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_IMGITOOLS
+
+ imgTools();
+
+ private:
+ virtual ~imgTools();
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_imgITools_h
diff --git a/image/moz.build b/image/moz.build
new file mode 100644
index 0000000000..aab71c1362
--- /dev/null
+++ b/image/moz.build
@@ -0,0 +1,139 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DIRS += ["build", "decoders", "encoders"]
+if CONFIG["ENABLE_TESTS"]:
+ DIRS += ["test/gtest"]
+
+if CONFIG["FUZZING_INTERFACES"]:
+ DIRS += ["test/fuzzing"]
+
+with Files("**"):
+ BUG_COMPONENT = ("Core", "Graphics: ImageLib")
+
+BROWSER_CHROME_MANIFESTS += [
+ "test/browser/browser.ini",
+ "test/browser/browser_sandbox_headless.ini",
+]
+
+MOCHITEST_MANIFESTS += ["test/mochitest/mochitest.ini"]
+
+MOCHITEST_CHROME_MANIFESTS += ["test/mochitest/chrome.ini"]
+
+XPCSHELL_TESTS_MANIFESTS += ["test/unit/xpcshell.ini"]
+
+XPIDL_SOURCES += [
+ "imgICache.idl",
+ "imgIContainer.idl",
+ "imgIContainerDebug.idl",
+ "imgIEncoder.idl",
+ "imgILoader.idl",
+ "imgINotificationObserver.idl",
+ "imgIRequest.idl",
+ "imgIScriptedNotificationObserver.idl",
+ "imgITools.idl",
+ "nsIIconURI.idl",
+]
+
+XPIDL_MODULE = "imglib2"
+
+EXPORTS += [
+ "FrameTimeout.h",
+ "ImageBlocker.h",
+ "ImageCacheKey.h",
+ "ImageLogging.h",
+ "ImageMetadata.h",
+ "ImageOps.h",
+ "ImageRegion.h",
+ "ImgDrawResult.h",
+ "imgLoader.h",
+ "imgRequest.h",
+ "imgRequestProxy.h",
+ "IProgressObserver.h",
+ "Orientation.h",
+ "SurfaceCacheUtils.h",
+]
+
+EXPORTS.mozilla.image += [
+ "encoders/bmp/nsBMPEncoder.h",
+ "encoders/ico/nsICOEncoder.h",
+ "encoders/jpeg/nsJPEGEncoder.h",
+ "encoders/png/nsPNGEncoder.h",
+ "ICOFileHeaders.h",
+ "ImageMemoryReporter.h",
+ "Resolution.h",
+ "WebRenderImageProvider.h",
+]
+
+UNIFIED_SOURCES += [
+ "AnimationFrameBuffer.cpp",
+ "AnimationSurfaceProvider.cpp",
+ "BlobSurfaceProvider.cpp",
+ "ClippedImage.cpp",
+ "DecodedSurfaceProvider.cpp",
+ "Decoder.cpp",
+ "DecoderFactory.cpp",
+ "DynamicImage.cpp",
+ "FrameAnimator.cpp",
+ "FrozenImage.cpp",
+ "IDecodingTask.cpp",
+ "Image.cpp",
+ "ImageBlocker.cpp",
+ "ImageCacheKey.cpp",
+ "ImageFactory.cpp",
+ "ImageMemoryReporter.cpp",
+ "ImageOps.cpp",
+ "ImageWrapper.cpp",
+ "imgFrame.cpp",
+ "imgLoader.cpp",
+ "imgRequest.cpp",
+ "imgRequestProxy.cpp",
+ "imgTools.cpp",
+ "MultipartImage.cpp",
+ "OrientedImage.cpp",
+ "ProgressTracker.cpp",
+ "RasterImage.cpp",
+ "ScriptedNotificationObserver.cpp",
+ "ShutdownTracker.cpp",
+ "SourceBuffer.cpp",
+ "SurfaceCache.cpp",
+ "SurfaceCacheUtils.cpp",
+ "SurfacePipe.cpp",
+ "SVGDocumentWrapper.cpp",
+ "VectorImage.cpp",
+]
+
+UNIFIED_SOURCES += ["Downscaler.cpp"]
+
+if CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
+ SOURCES += ["DecodePool.cpp"]
+else:
+ UNIFIED_SOURCES += ["DecodePool.cpp"]
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+FINAL_LIBRARY = "xul"
+
+LOCAL_INCLUDES += [
+ # Because SVGDocumentWrapper.cpp includes "mozilla/dom/SVGSVGElement.h"
+ "/dom/base",
+ "/dom/svg",
+ # Because imgFrame.cpp includes "cairo.h"
+ "/gfx/cairo/cairo/src",
+ # We need to instantiate the decoders
+ "/image/decoders",
+ # For URI-related functionality
+ "/netwerk/base",
+ # For nsHttpChannel.h
+ "/netwerk/protocol/http",
+ # DecodePool uses thread-related facilities.
+ "/xpcom/threads",
+]
+
+LOCAL_INCLUDES += CONFIG["SKIA_INCLUDES"]
+
+# Add libFuzzer configuration directives
+include("/tools/fuzzing/libfuzzer-config.mozbuild")
diff --git a/image/nsIIconURI.idl b/image/nsIIconURI.idl
new file mode 100644
index 0000000000..b55ee8d8c7
--- /dev/null
+++ b/image/nsIIconURI.idl
@@ -0,0 +1,92 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIURL.idl"
+
+ /**
+ * nsIIconURI
+ *
+ * This interface derives from nsIURI, to provide additional information
+ * about moz-icon URIs.
+ *
+ * What *is* a moz-icon URI you ask? Well, it has the following syntax:
+ *
+ * moz-icon:[<valid-url> | //<file-with-extension> | //stock/<stock-icon>]?
+ * ['?'[<parameter-value-pairs>]]
+ *
+ * <valid-url> is a valid URL spec.
+ *
+ * <file-with-extension> is any filename with an extension, e.g. "dummy.html".
+ * If the file you want an icon for isn't known to exist, you can use this
+ * instead of a URL and just place a dummy file name with the extension or
+ * content type you want.
+ *
+ * <stock-icon> is the name of a platform-dependant stock icon.
+ *
+ * Legal parameter value pairs are listed below:
+ *
+ * Parameter: size
+ * Values: [<integer> | button | toolbar | toolbarsmall | menu |
+ * dialog]
+ * Description: If integer, this is the desired size in square pixels of
+ * the icon
+ * Else, use the OS default for the specified keyword context.
+ *
+ * Parameter: state
+ * Values: [normal | disabled]
+ * Description: The state of the icon.
+ *
+ * Parameter: contentType
+ * Values: <mime-type>
+ * Description: The mime type we want an icon for. This is ignored by
+ * stock images.
+ */
+
+[scriptable, builtinclass, uuid(f8fe5ef2-5f2b-43f3-857d-5b64d192c427)]
+interface nsIMozIconURI : nsIURI
+{
+ /// iconFile: the file URL contained within this moz-icon url, or null.
+ readonly attribute nsIURL iconURL;
+
+ /// imageSize: The image area in square pixels, defaults to 16 if unspecified.
+ readonly attribute unsigned long imageSize;
+
+ /// stockIcon: The stock icon name requested from the OS.
+ readonly attribute ACString stockIcon;
+
+ /// iconSize: The stock icon size requested from the OS.
+ readonly attribute ACString iconSize;
+
+ /// iconState: The stock icon state requested from the OS.
+ readonly attribute ACString iconState;
+
+ /// contentType: A valid mime type, or the empty string.
+ readonly attribute ACString contentType;
+
+ /// fileExtension: The file extension of the file which we are looking up.
+ readonly attribute ACString fileExtension;
+};
+
+%{C++
+
+// CID for nsMozIconURI, if implemented on this platform.
+#define NS_MOZICONURI_CID \
+{ \
+ 0x43a88e0e, \
+ 0x2d37, \
+ 0x11d5, \
+ { 0x99, 0x7, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b } \
+}
+
+#define NS_MOZICONURIMUTATOR_CID \
+{ \
+ 0x1460df3b, \
+ 0x774c, \
+ 0x4205, \
+ {0x83, 0x49, 0x83, 0x8e, 0x50, 0x7c, 0x3e, 0xf9} \
+}
+
+%}
diff --git a/image/test/browser/animated.gif b/image/test/browser/animated.gif
new file mode 100644
index 0000000000..eb034e1501
--- /dev/null
+++ b/image/test/browser/animated.gif
Binary files differ
diff --git a/image/test/browser/animated2.gif b/image/test/browser/animated2.gif
new file mode 100644
index 0000000000..053eaae688
--- /dev/null
+++ b/image/test/browser/animated2.gif
Binary files differ
diff --git a/image/test/browser/big.png b/image/test/browser/big.png
new file mode 100644
index 0000000000..94e7eb6db2
--- /dev/null
+++ b/image/test/browser/big.png
Binary files differ
diff --git a/image/test/browser/browser.ini b/image/test/browser/browser.ini
new file mode 100644
index 0000000000..b5ba8581a3
--- /dev/null
+++ b/image/test/browser/browser.ini
@@ -0,0 +1,20 @@
+[DEFAULT]
+support-files =
+ animated.gif
+ animated2.gif
+ big.png
+ head.js
+ image.html
+ imageX2.html
+ browser_docshell_type_editor/**
+
+[browser_bug666317.js]
+skip-if = true # Bug 1207012 - Permaorange from an uncaught exception that isn't actually turning the suite orange until it hits beta, Bug 948194 - Decoded Images seem to not be discarded on memory-pressure notification
+[browser_image.js]
+skip-if = true # Bug 987616
+[browser_docshell_type_editor.js]
+[browser_offscreen_image_in_out_of_process_iframe.js]
+https_first_disabled = true
+support-files =
+ empty.html
+[browser_mozicon_file.js]
diff --git a/image/test/browser/browser_bug666317.js b/image/test/browser/browser_bug666317.js
new file mode 100644
index 0000000000..7f58c61c56
--- /dev/null
+++ b/image/test/browser/browser_bug666317.js
@@ -0,0 +1,138 @@
+waitForExplicitFinish();
+
+var pageSource =
+ "<html><body>" +
+ '<img id="testImg" src="' +
+ TESTROOT +
+ 'big.png">' +
+ "</body></html>";
+
+var oldDiscardingPref, oldTab, newTab;
+var prefBranch = Services.prefs.getBranch("image.mem.");
+
+var gWaitingForDiscard = false;
+var gScriptedObserver;
+var gClonedRequest;
+
+function ImageObserver(decodeCallback, discardCallback) {
+ this.decodeComplete = function onDecodeComplete(aRequest) {
+ decodeCallback();
+ };
+
+ this.discard = function onDiscard(request) {
+ if (!gWaitingForDiscard) {
+ return;
+ }
+
+ this.synchronous = false;
+ discardCallback();
+ };
+
+ this.synchronous = true;
+}
+
+function currentRequest() {
+ let img = gBrowser
+ .getBrowserForTab(newTab)
+ .contentWindow.document.getElementById("testImg");
+ return img.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
+}
+
+function isImgDecoded() {
+ let request = currentRequest();
+ return !!(request.imageStatus & Ci.imgIRequest.STATUS_DECODE_COMPLETE);
+}
+
+// Ensure that the image is decoded by drawing it to a canvas.
+function forceDecodeImg() {
+ let doc = gBrowser.getBrowserForTab(newTab).contentWindow.document;
+ let img = doc.getElementById("testImg");
+ let canvas = doc.createElement("canvas");
+ let ctx = canvas.getContext("2d");
+ ctx.drawImage(img, 0, 0);
+}
+
+function runAfterAsyncEvents(aCallback) {
+ function handlePostMessage(aEvent) {
+ if (aEvent.data == "next") {
+ window.removeEventListener("message", handlePostMessage);
+ aCallback();
+ }
+ }
+
+ window.addEventListener("message", handlePostMessage);
+
+ // We'll receive the 'message' event after everything else that's currently in
+ // the event queue (which is a stronger guarantee than setTimeout, because
+ // setTimeout events may be coalesced). This lets us ensure that we run
+ // aCallback *after* any asynchronous events are delivered.
+ window.postMessage("next", "*");
+}
+
+function test() {
+ // Enable the discarding pref.
+ oldDiscardingPref = prefBranch.getBoolPref("discardable");
+ prefBranch.setBoolPref("discardable", true);
+
+ // Create and focus a new tab.
+ oldTab = gBrowser.selectedTab;
+ newTab = BrowserTestUtils.addTab(gBrowser, "data:text/html," + pageSource);
+ gBrowser.selectedTab = newTab;
+
+ // Run step2 after the tab loads.
+ gBrowser.getBrowserForTab(newTab).addEventListener("pageshow", step2);
+}
+
+function step2() {
+ // Create the image observer.
+ var observer = new ImageObserver(
+ () => runAfterAsyncEvents(step3), // DECODE_COMPLETE
+ () => runAfterAsyncEvents(step5)
+ ); // DISCARD
+ gScriptedObserver = Cc["@mozilla.org/image/tools;1"]
+ .getService(Ci.imgITools)
+ .createScriptedObserver(observer);
+
+ // Clone the current imgIRequest with our new observer.
+ var request = currentRequest();
+ gClonedRequest = request.clone(gScriptedObserver);
+
+ // Check that the image is decoded.
+ forceDecodeImg();
+
+ // The DECODE_COMPLETE notification is delivered asynchronously. ImageObserver will
+ // eventually call step3.
+}
+
+function step3() {
+ ok(isImgDecoded(), "Image should initially be decoded.");
+
+ // Focus the old tab, then fire a memory-pressure notification. This should
+ // cause the decoded image in the new tab to be discarded.
+ gBrowser.selectedTab = oldTab;
+
+ // Allow time to process the tab change.
+ runAfterAsyncEvents(step4);
+}
+
+function step4() {
+ gWaitingForDiscard = true;
+
+ var os = Services.obs;
+ os.notifyObservers(null, "memory-pressure", "heap-minimize");
+
+ // The DISCARD notification is delivered asynchronously. ImageObserver will
+ // eventually call step5. (Or else, sadly, the test will time out.)
+}
+
+function step5() {
+ ok(true, "Image should be discarded.");
+
+ // And we're done.
+ gBrowser.removeTab(newTab);
+ prefBranch.setBoolPref("discardable", oldDiscardingPref);
+
+ gClonedRequest.cancelAndForgetObserver(0);
+
+ finish();
+}
diff --git a/image/test/browser/browser_docshell_type_editor.js b/image/test/browser/browser_docshell_type_editor.js
new file mode 100644
index 0000000000..baa89c0f07
--- /dev/null
+++ b/image/test/browser/browser_docshell_type_editor.js
@@ -0,0 +1,134 @@
+"use strict";
+
+const SIMPLE_HTML = "data:text/html,<html><head></head><body></body></html>";
+
+/**
+ * Returns the directory where the chrome.manifest file for the test can be found.
+ *
+ * @return nsIFile of the manifest directory
+ */
+function getManifestDir() {
+ let path = getTestFilePath("browser_docshell_type_editor");
+ let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+ file.initWithPath(path);
+ return file;
+}
+
+// The following URI is *not* accessible to content, hence loading that URI
+// from an unprivileged site should be blocked. If docshell is of appType
+// APP_TYPE_EDITOR however the load should be allowed.
+// >> chrome://test1/skin/privileged.png
+
+add_task(async function () {
+ info("docshell of appType APP_TYPE_EDITOR can access privileged images.");
+
+ // Load a temporary manifest adding a route to a privileged image
+ let manifestDir = getManifestDir();
+ Components.manager.addBootstrappedManifestLocation(manifestDir);
+
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: SIMPLE_HTML,
+ },
+ async function (browser) {
+ await SpecialPowers.spawn(browser, [], async function () {
+ let rootDocShell = docShell.sameTypeRootTreeItem.QueryInterface(
+ Ci.nsIDocShell
+ );
+ let defaultAppType = rootDocShell.appType;
+
+ rootDocShell.appType = Ci.nsIDocShell.APP_TYPE_EDITOR;
+
+ is(
+ rootDocShell.appType,
+ Ci.nsIDocShell.APP_TYPE_EDITOR,
+ "sanity check: appType after update should be type editor"
+ );
+
+ return new Promise(resolve => {
+ let doc = content.document;
+ let image = doc.createElement("img");
+ image.onload = function () {
+ ok(true, "APP_TYPE_EDITOR is allowed to load privileged image");
+ // restore appType of rootDocShell before moving on to the next test
+ rootDocShell.appType = defaultAppType;
+ resolve();
+ };
+ image.onerror = function () {
+ ok(false, "APP_TYPE_EDITOR is allowed to load privileged image");
+ // restore appType of rootDocShell before moving on to the next test
+ rootDocShell.appType = defaultAppType;
+ resolve();
+ };
+ doc.body.appendChild(image);
+ image.src = "chrome://test1/skin/privileged.png";
+ });
+ });
+ }
+ );
+
+ Components.manager.removeBootstrappedManifestLocation(manifestDir);
+});
+
+add_task(async function () {
+ info(
+ "docshell of appType APP_TYPE_UNKNOWN can *not* access privileged images."
+ );
+
+ // Load a temporary manifest adding a route to a privileged image
+ let manifestDir = getManifestDir();
+ Components.manager.addBootstrappedManifestLocation(manifestDir);
+
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: SIMPLE_HTML,
+ },
+ async function (browser) {
+ await SpecialPowers.spawn(browser, [], async function () {
+ let rootDocShell = docShell.sameTypeRootTreeItem.QueryInterface(
+ Ci.nsIDocShell
+ );
+ let defaultAppType = rootDocShell.appType;
+
+ rootDocShell.appType = Ci.nsIDocShell.APP_TYPE_UNKNOWN;
+
+ is(
+ rootDocShell.appType,
+ Ci.nsIDocShell.APP_TYPE_UNKNOWN,
+ "sanity check: appType of docshell should be unknown"
+ );
+
+ return new Promise(resolve => {
+ let doc = content.document;
+ let image = doc.createElement("img");
+ image.onload = function () {
+ ok(
+ false,
+ "APP_TYPE_UNKNOWN is *not* allowed to access privileged image"
+ );
+ // restore appType of rootDocShell before moving on to the next test
+ rootDocShell.appType = defaultAppType;
+ resolve();
+ };
+ image.onerror = function () {
+ ok(
+ true,
+ "APP_TYPE_UNKNOWN is *not* allowed to access privileged image"
+ );
+ // restore appType of rootDocShell before moving on to the next test
+ rootDocShell.appType = defaultAppType;
+ resolve();
+ };
+ doc.body.appendChild(image);
+ // Set the src via wrappedJSObject so the load is triggered with
+ // the content page's principal rather than ours.
+ image.wrappedJSObject.src = "chrome://test1/skin/privileged.png";
+ });
+ });
+ }
+ );
+
+ Components.manager.removeBootstrappedManifestLocation(manifestDir);
+});
diff --git a/image/test/browser/browser_docshell_type_editor/chrome.manifest b/image/test/browser/browser_docshell_type_editor/chrome.manifest
new file mode 100644
index 0000000000..85510a8af9
--- /dev/null
+++ b/image/test/browser/browser_docshell_type_editor/chrome.manifest
@@ -0,0 +1 @@
+skin test1 test img/ \ No newline at end of file
diff --git a/image/test/browser/browser_docshell_type_editor/img/privileged.png b/image/test/browser/browser_docshell_type_editor/img/privileged.png
new file mode 100644
index 0000000000..2bf7b7e828
--- /dev/null
+++ b/image/test/browser/browser_docshell_type_editor/img/privileged.png
Binary files differ
diff --git a/image/test/browser/browser_image.js b/image/test/browser/browser_image.js
new file mode 100644
index 0000000000..0ae55df640
--- /dev/null
+++ b/image/test/browser/browser_image.js
@@ -0,0 +1,261 @@
+waitForExplicitFinish();
+requestLongerTimeout(2); // see bug 660123 -- this test is slow on Mac.
+
+// A hold on the current timer, so it doesn't get GCed out from
+// under us
+var gTimer;
+
+// Browsing to a new URL - pushing us into the bfcache - should cause
+// animations to stop, and resume when we return
+/* global yield */
+function testBFCache() {
+ function theTest() {
+ var abort = false;
+ var chances, gImage, gFrames;
+ gBrowser.selectedTab = BrowserTestUtils.addTab(
+ gBrowser,
+ TESTROOT + "image.html"
+ );
+ gBrowser.selectedBrowser.addEventListener(
+ "pageshow",
+ function () {
+ var window = gBrowser.contentWindow;
+ // If false, we are in an optimized build, and we abort this and
+ // all further tests
+ if (
+ !actOnMozImage(window.document, "img1", function (image) {
+ gImage = image;
+ gFrames = gImage.framesNotified;
+ })
+ ) {
+ gBrowser.removeCurrentTab();
+ abort = true;
+ }
+ goer.next();
+ },
+ { capture: true, once: true }
+ );
+ yield;
+ if (abort) {
+ finish();
+ yield; // optimized build
+ }
+
+ // Let animation run for a bit
+ chances = 120;
+ do {
+ gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ gTimer.initWithCallback(
+ function () {
+ if (gImage.framesNotified >= 20) {
+ goer.send(true);
+ } else {
+ chances--;
+ goer.send(chances == 0); // maybe if we wait a bit, it will happen
+ }
+ },
+ 500,
+ Ci.nsITimer.TYPE_ONE_SHOT
+ );
+ } while (!yield);
+ is(chances > 0, true, "Must have animated a few frames so far");
+
+ // Browse elsewhere; push our animating page into the bfcache
+ gBrowser.loadURI(Services.io.newURI("about:blank"));
+
+ // Wait a bit for page to fully load, then wait a while and
+ // see that no animation occurs.
+ gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ gTimer.initWithCallback(
+ function () {
+ gFrames = gImage.framesNotified;
+ gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ gTimer.initWithCallback(
+ function () {
+ // Might have a few stray frames, until other page totally loads
+ var additionalFrames = gImage.framesNotified - gFrames;
+ is(
+ additionalFrames == 0,
+ true,
+ "Must have not animated in bfcache! Got " +
+ additionalFrames +
+ " additional frames"
+ );
+ goer.next();
+ },
+ 4000,
+ Ci.nsITimer.TYPE_ONE_SHOT
+ ); // 4 seconds - expect 40 frames
+ },
+ 0,
+ Ci.nsITimer.TYPE_ONE_SHOT
+ ); // delay of 0 - wait for next event loop
+ yield;
+
+ // Go back
+ gBrowser.goBack();
+
+ chances = 120;
+ do {
+ gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ gTimer.initWithCallback(
+ function () {
+ if (gImage.framesNotified - gFrames >= 20) {
+ goer.send(true);
+ } else {
+ chances--;
+ goer.send(chances == 0); // maybe if we wait a bit, it will happen
+ }
+ },
+ 500,
+ Ci.nsITimer.TYPE_ONE_SHOT
+ );
+ } while (!yield);
+ is(chances > 0, true, "Must have animated once out of bfcache!");
+
+ // Finally, check that the css background image has essentially the same
+ // # of frames, implying that it animated at the same times as the regular
+ // image. We can easily retrieve regular images through their HTML image
+ // elements, which is what we did before. For the background image, we
+ // create a regular image now, and read the current frame count.
+ var doc = gBrowser.selectedBrowser.contentWindow.document;
+ var div = doc.getElementById("background_div");
+ div.innerHTML += '<img src="animated2.gif" id="img3">';
+ actOnMozImage(doc, "img3", function (image) {
+ is(
+ Math.abs(image.framesNotified - gImage.framesNotified) /
+ gImage.framesNotified <
+ 0.5,
+ true,
+ "Must have also animated the background image, and essentially the same # of frames. " +
+ "Regular image got " +
+ gImage.framesNotified +
+ " frames but background image got " +
+ image.framesNotified
+ );
+ });
+
+ gBrowser.removeCurrentTab();
+
+ nextTest();
+ }
+
+ var goer = theTest();
+ goer.next();
+}
+
+// Check that imgContainers are shared on the same page and
+// between tabs
+function testSharedContainers() {
+ function theTest() {
+ var gImages = [];
+ var gFrames;
+
+ gBrowser.selectedTab = BrowserTestUtils.addTab(
+ gBrowser,
+ TESTROOT + "image.html"
+ );
+ gBrowser.selectedBrowser.addEventListener(
+ "pageshow",
+ function () {
+ actOnMozImage(gBrowser.contentDocument, "img1", function (image) {
+ gImages[0] = image;
+ gFrames = image.framesNotified; // May in theory have frames from last test
+ // in this counter - so subtract them out
+ });
+ goer.next();
+ },
+ { capture: true, once: true }
+ );
+ yield;
+
+ // Load next tab somewhat later
+ gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ gTimer.initWithCallback(
+ function () {
+ goer.next();
+ },
+ 1500,
+ Ci.nsITimer.TYPE_ONE_SHOT
+ );
+ yield;
+
+ gBrowser.selectedTab = BrowserTestUtils.addTab(
+ gBrowser,
+ TESTROOT + "imageX2.html"
+ );
+ gBrowser.selectedBrowser.addEventListener(
+ "pageshow",
+ function () {
+ [1, 2].forEach(function (i) {
+ actOnMozImage(gBrowser.contentDocument, "img" + i, function (image) {
+ gImages[i] = image;
+ });
+ });
+ goer.next();
+ },
+ { capture: true, once: true }
+ );
+ yield;
+
+ var chances = 120;
+ do {
+ gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ gTimer.initWithCallback(
+ function () {
+ if (gImages[0].framesNotified - gFrames >= 10) {
+ goer.send(true);
+ } else {
+ chances--;
+ goer.send(chances == 0); // maybe if we wait a bit, it will happen
+ }
+ },
+ 500,
+ Ci.nsITimer.TYPE_ONE_SHOT
+ );
+ } while (!yield);
+ is(
+ chances > 0,
+ true,
+ "Must have been animating while showing several images"
+ );
+
+ // Check they all have the same frame counts
+ var theFrames = null;
+ [0, 1, 2].forEach(function (i) {
+ var frames = gImages[i].framesNotified;
+ if (theFrames == null) {
+ theFrames = frames;
+ } else {
+ is(
+ theFrames,
+ frames,
+ "Sharing the same imgContainer means *exactly* the same frame counts!"
+ );
+ }
+ });
+
+ gBrowser.removeCurrentTab();
+ gBrowser.removeCurrentTab();
+
+ nextTest();
+ }
+
+ var goer = theTest();
+ goer.next();
+}
+
+var tests = [testBFCache, testSharedContainers];
+
+function nextTest() {
+ if (!tests.length) {
+ finish();
+ return;
+ }
+ tests.shift()();
+}
+
+function test() {
+ ignoreAllUncaughtExceptions();
+ nextTest();
+}
diff --git a/image/test/browser/browser_mozicon_file.js b/image/test/browser/browser_mozicon_file.js
new file mode 100644
index 0000000000..8e01e0484d
--- /dev/null
+++ b/image/test/browser/browser_mozicon_file.js
@@ -0,0 +1,12 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+add_task(async function test_mozicon_file_no_sandbox() {
+ assertFileProcess();
+ await createMozIconInFile("txt");
+ await createMozIconInFile("exe");
+ await createMozIconInFile("non-existent-bidule");
+});
diff --git a/image/test/browser/browser_mozicon_file_sandbox_headless.js b/image/test/browser/browser_mozicon_file_sandbox_headless.js
new file mode 100644
index 0000000000..08e8689904
--- /dev/null
+++ b/image/test/browser/browser_mozicon_file_sandbox_headless.js
@@ -0,0 +1,13 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+add_task(async function test_mozicon_file_with_sandbox() {
+ assertFileProcess();
+ assertSandboxHeadless();
+ await createMozIconInFile("txt");
+ await createMozIconInFile("exe");
+ await createMozIconInFile("non-existent-bidule");
+});
diff --git a/image/test/browser/browser_offscreen_image_in_out_of_process_iframe.js b/image/test/browser/browser_offscreen_image_in_out_of_process_iframe.js
new file mode 100644
index 0000000000..71b34a4715
--- /dev/null
+++ b/image/test/browser/browser_offscreen_image_in_out_of_process_iframe.js
@@ -0,0 +1,164 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const DIRPATH = getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content/",
+ ""
+);
+const parentPATH = DIRPATH + "empty.html";
+const iframePATH = DIRPATH + "empty.html";
+
+const parentURL = `http://example.com/${parentPATH}`;
+const iframeURL = `http://example.org/${iframePATH}`;
+
+add_task(async function setup_pref() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ // To avoid throttling requestAnimationFrame callbacks in invisible
+ // iframes
+ ["layout.throttled_frame_rate", 60],
+ ],
+ });
+});
+
+add_task(async function () {
+ const win = await BrowserTestUtils.openNewBrowserWindow({
+ fission: true,
+ });
+
+ try {
+ const browser = win.gBrowser.selectedTab.linkedBrowser;
+
+ BrowserTestUtils.loadURIString(browser, parentURL);
+ await BrowserTestUtils.browserLoaded(browser, false, parentURL);
+
+ async function setup(url) {
+ const scroller = content.document.createElement("div");
+ scroller.style = "width: 300px; height: 300px; overflow: scroll;";
+ scroller.setAttribute("id", "scroller");
+ content.document.body.appendChild(scroller);
+
+ // Make a space bigger than display port.
+ const spacer = content.document.createElement("div");
+ spacer.style = "width: 100%; height: 10000px;";
+ scroller.appendChild(spacer);
+
+ const iframe = content.document.createElement("iframe");
+ scroller.appendChild(iframe);
+
+ iframe.contentWindow.location = url;
+ await new Promise(resolve => {
+ iframe.addEventListener("load", resolve, { once: true });
+ });
+
+ return iframe.browsingContext;
+ }
+
+ async function setupImage() {
+ const img = content.document.createElement("img");
+ // This GIF is a 100ms interval animation.
+ img.setAttribute("src", "animated.gif");
+ img.setAttribute("id", "img");
+ content.document.body.appendChild(img);
+
+ const spacer = content.document.createElement("div");
+ spacer.style = "width: 100%; height: 10000px;";
+ content.document.body.appendChild(spacer);
+ await new Promise(resolve => {
+ img.addEventListener("load", resolve, { once: true });
+ });
+ }
+
+ // Returns the count of frameUpdate during |time| (in ms) period.
+ async function observeFrameUpdate(time) {
+ function ImageDecoderObserverStub() {
+ this.sizeAvailable = function sizeAvailable(aRequest) {};
+ this.frameComplete = function frameComplete(aRequest) {};
+ this.decodeComplete = function decodeComplete(aRequest) {};
+ this.loadComplete = function loadComplete(aRequest) {};
+ this.frameUpdate = function frameUpdate(aRequest) {};
+ this.discard = function discard(aRequest) {};
+ this.isAnimated = function isAnimated(aRequest) {};
+ this.hasTransparency = function hasTransparency(aRequest) {};
+ }
+
+ // Start from the callback of setTimeout.
+ await new Promise(resolve => content.window.setTimeout(resolve, 0));
+
+ let frameCount = 0;
+ const observer = new ImageDecoderObserverStub();
+ observer.frameUpdate = () => {
+ frameCount++;
+ };
+ observer.loadComplete = () => {
+ // Ignore the frameUpdate callback along with loadComplete. It seems
+ // a frameUpdate sometimes happens with a loadComplete when attatching
+ // observer in fission world.
+ frameCount--;
+ };
+
+ const gObserver = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
+ .getService(SpecialPowers.Ci.imgITools)
+ .createScriptedObserver(observer);
+ const img = content.document.getElementById("img");
+
+ SpecialPowers.wrap(img).addObserver(gObserver);
+ await new Promise(resolve => content.window.setTimeout(resolve, time));
+ SpecialPowers.wrap(img).removeObserver(gObserver);
+
+ return frameCount;
+ }
+
+ // Setup an iframe which is initially scrolled out.
+ const iframe = await SpecialPowers.spawn(browser, [iframeURL], setup);
+
+ // Setup a 100ms interval animated GIF image in the iframe.
+ await SpecialPowers.spawn(iframe, [], setupImage);
+
+ let frameCount = await SpecialPowers.spawn(
+ iframe,
+ [1000],
+ observeFrameUpdate
+ );
+ // Bug 1577084.
+ if (frameCount == 0) {
+ is(frameCount, 0, "no frameupdates");
+ } else {
+ todo_is(frameCount, 0, "no frameupdates");
+ }
+
+ // Scroll the iframe into view.
+ await SpecialPowers.spawn(browser, [], async () => {
+ const scroller = content.document.getElementById("scroller");
+ scroller.scrollTo({ left: 0, top: 9800, behavior: "smooth" });
+ await new Promise(resolve => content.window.setTimeout(resolve, 1000));
+ });
+
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ frameCount = await SpecialPowers.spawn(iframe, [1000], observeFrameUpdate);
+ ok(frameCount > 0, "There should be frameUpdate(s)");
+
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ await SpecialPowers.spawn(iframe, [], async () => {
+ const img = content.document.getElementById("img");
+ // Move the image outside of the scroll port. 'position: absolute' causes
+ // a relow on the image element.
+ img.style = "position: absolute; top: 9000px;";
+ await new Promise(resolve =>
+ content.window.requestAnimationFrame(resolve)
+ );
+ });
+
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ frameCount = await SpecialPowers.spawn(iframe, [1000], observeFrameUpdate);
+ is(frameCount, 0, "No frameUpdate should happen");
+ } finally {
+ await BrowserTestUtils.closeWindow(win);
+ }
+});
diff --git a/image/test/browser/browser_sandbox_headless.ini b/image/test/browser/browser_sandbox_headless.ini
new file mode 100644
index 0000000000..70cd0147ca
--- /dev/null
+++ b/image/test/browser/browser_sandbox_headless.ini
@@ -0,0 +1,8 @@
+[DEFAULT]
+support-files =
+ head.js
+prefs =
+ security.sandbox.content.headless=true
+skip-if = (os != 'linux') # the pref is only used on linux
+
+[browser_mozicon_file_sandbox_headless.js]
diff --git a/image/test/browser/empty.html b/image/test/browser/empty.html
new file mode 100644
index 0000000000..a31dad3630
--- /dev/null
+++ b/image/test/browser/empty.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
diff --git a/image/test/browser/head.js b/image/test/browser/head.js
new file mode 100644
index 0000000000..29fc67a1a7
--- /dev/null
+++ b/image/test/browser/head.js
@@ -0,0 +1,136 @@
+const RELATIVE_DIR = "image/test/browser/";
+const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
+const TESTROOT2 = "http://example.org/browser/" + RELATIVE_DIR;
+
+var chrome_root = getRootDirectory(gTestPath);
+const CHROMEROOT = chrome_root;
+
+function getImageLoading(doc, id) {
+ return doc.getElementById(id);
+}
+
+// Tries to get the Moz debug image, imgIContainerDebug. Only works
+// in a debug build. If we succeed, we call func().
+function actOnMozImage(doc, id, func) {
+ var imgContainer = getImageLoading(doc, id).getRequest(
+ Ci.nsIImageLoadingContent.CURRENT_REQUEST
+ ).image;
+ var mozImage;
+ try {
+ mozImage = imgContainer.QueryInterface(Ci.imgIContainerDebug);
+ } catch (e) {
+ return false;
+ }
+ func(mozImage);
+ return true;
+}
+
+function assertPrefVal(name, val) {
+ let boolValue = Services.prefs.getBoolPref(name);
+ ok(boolValue === val, `pref ${name} is set to ${val}`);
+ if (boolValue !== val) {
+ throw Error(`pref ${name} is not set to ${val}`);
+ }
+}
+
+function assertFileProcess() {
+ // Ensure that the file content process is enabled.
+ assertPrefVal("browser.tabs.remote.separateFileUriProcess", true);
+}
+
+function assertSandboxHeadless() {
+ assertPrefVal("security.sandbox.content.headless", true);
+}
+
+function getPage() {
+ let filePage = undefined;
+ switch (Services.appinfo.OS) {
+ case "WINNT":
+ filePage = "file:///C:/";
+ break;
+ case "Darwin":
+ filePage = "file:///tmp/";
+ break;
+ case "Linux":
+ filePage = "file:///tmp/";
+ break;
+ default:
+ throw new Error("Unsupported operating system");
+ }
+ return filePage;
+}
+
+function getSize() {
+ let iconSize = undefined;
+ switch (Services.appinfo.OS) {
+ case "WINNT":
+ iconSize = 32;
+ break;
+ case "Darwin":
+ iconSize = 128;
+ break;
+ case "Linux":
+ iconSize = 128;
+ break;
+ default:
+ throw new Error("Unsupported operating system");
+ }
+ return iconSize;
+}
+
+async function createMozIconInFile(ext, expectSuccess = true) {
+ const kPAGE = getPage();
+ const kSize = expectSuccess ? getSize() : 24; // we get 24x24 when failing,
+ // e.g. when remoting is
+ // disabled and the sandbox
+ // headless is enabled
+
+ // open a tab in a file content process
+ let fileTab = await BrowserTestUtils.addTab(gBrowser, kPAGE, {
+ preferredRemoteType: "file",
+ });
+
+ // get the browser for the file content process tab
+ let fileBrowser = gBrowser.getBrowserForTab(fileTab);
+
+ let checkIcon = async (_ext, _kSize, _expectSuccess) => {
+ const img = content.document.createElement("img");
+ let waitLoad = new Promise(resolve => {
+ // only listen to successfull load event if we expect the image to
+ // actually load, e.g. with remoting disabled and sandbox headless
+ // enabled we dont expect it to work, and we will wait for onerror below
+ // to trigger.
+ if (_expectSuccess) {
+ img.addEventListener("load", resolve, { once: true });
+ }
+ img.onerror = () => {
+ // With remoting enabled,
+ // Verified to work by forcing early `return NS_ERROR_NOT_AVAILABLE;`
+ // within `nsIconChannel::GetIcon(nsIURI* aURI, ByteBuf* aDataOut)`
+ //
+ // With remoting disabled and sandbox headless enabled, this should be
+ // the default path, since we don't add the "load" event listener.
+ ok(!_expectSuccess, "Error while loading moz-icon");
+ resolve();
+ };
+ });
+ img.setAttribute("src", `moz-icon://.${_ext}?size=${_kSize}`);
+ img.setAttribute("id", `moz-icon-${_ext}-${_kSize}`);
+ content.document.body.appendChild(img);
+
+ await waitLoad;
+
+ const icon = content.document.getElementById(`moz-icon-${_ext}-${_kSize}`);
+ ok(icon !== null, `got a valid ${_ext} moz-icon`);
+ is(icon.width, _kSize, `${_kSize} px width ${_ext} moz-icon`);
+ is(icon.height, _kSize, `${_kSize} px height ${_ext} moz-icon`);
+ };
+
+ await BrowserTestUtils.browserLoaded(fileBrowser);
+ await SpecialPowers.spawn(
+ fileBrowser,
+ [ext, kSize, expectSuccess],
+ checkIcon
+ );
+ await BrowserTestUtils.removeTab(fileTab);
+}
diff --git a/image/test/browser/image.html b/image/test/browser/image.html
new file mode 100644
index 0000000000..3831ab68a4
--- /dev/null
+++ b/image/test/browser/image.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html>
+ <head>
+ <title>Imagelib2 animation tests</title>
+ <style type="text/css">
+ #background_div {
+ border: 1px black solid;
+ height: 200px;
+ width: 200px;
+ margin: 10px;
+ background: url(animated2.gif) center center no-repeat;
+ }
+ </style>
+ </head>
+ </head>
+<body>
+ <p>Page with image</p>
+ <img src="animated.gif" id="img1">
+ <div id="background_div"></div>
+</body>
+</html>
diff --git a/image/test/browser/imageX2.html b/image/test/browser/imageX2.html
new file mode 100644
index 0000000000..4ce953bfac
--- /dev/null
+++ b/image/test/browser/imageX2.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html>
+ <head>
+ <title>Imagelib2 animation tests</title>
+ </head>
+<body>
+ <p>Page with images</p>
+ <img src="animated.gif" id="img1">
+ <br>
+ <img src="animated.gif" id="img2">
+</body>
+</html>
diff --git a/image/test/crashtests/1205923-1.html b/image/test/crashtests/1205923-1.html
new file mode 100644
index 0000000000..456fc51b6e
--- /dev/null
+++ b/image/test/crashtests/1205923-1.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<body>
+</body>
+<script>
+ function createImage(loadHandler) {
+ var newImage = new Image;
+ newImage.id = "thepreviewimage";
+ newImage.setAttribute("src", "unsized-svg.svg");
+ if (loadHandler) {
+ newImage.onload = loadHandler;
+ }
+
+ // Query width & height, and display them in document:
+ physWidth = newImage.width;
+ physHeight = newImage.height;
+ document.documentElement.innerHTML +=
+ physWidth + " x " + physHeight + "<br>";
+ }
+
+ function part2() {
+ // Load image again:
+ createImage();
+
+ // End the crashtest.
+ document.documentElement.removeAttribute("class");
+ }
+
+ function startTest() {
+ // Trigger image load, and call part2() when it's loaded:
+ createImage(part2);
+ }
+
+ startTest();
+</script>
+</html>
diff --git a/image/test/crashtests/1210745-1.gif b/image/test/crashtests/1210745-1.gif
new file mode 100644
index 0000000000..92bcf72224
--- /dev/null
+++ b/image/test/crashtests/1210745-1.gif
Binary files differ
diff --git a/image/test/crashtests/1212954-1.svg b/image/test/crashtests/1212954-1.svg
new file mode 100644
index 0000000000..83dd7b9c7f
--- /dev/null
+++ b/image/test/crashtests/1212954-1.svg
@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <defs>
+ <filter id="f">
+ <!-- the image data is
+ <svg xmlns="http://www.w3.org/2000/svg" width="-5" height="1%" />
+ -->
+ <feImage xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSItNSIgaGVpZ2h0
+PSIxJSIgLz4K" />
+ </filter>
+ </defs>
+
+ <rect width="1" height="1" filter="url(#f)" />
+
+</svg>
diff --git a/image/test/crashtests/1235605.gif b/image/test/crashtests/1235605.gif
new file mode 100644
index 0000000000..e7c3ea0b87
--- /dev/null
+++ b/image/test/crashtests/1235605.gif
Binary files differ
diff --git a/image/test/crashtests/1241728-1.html b/image/test/crashtests/1241728-1.html
new file mode 100644
index 0000000000..126c02e624
--- /dev/null
+++ b/image/test/crashtests/1241728-1.html
@@ -0,0 +1,17 @@
+<html>
+<body>
+<img id='m1' src='data:image/bmp;base64,Qk16AAAAAAAAAJUAABMoAAAAIA4AACAAACYBAAQAAgAAAAB/AAQCAADE9Sj/AAkAAAAAAAAR4AAAAAD/AAAA//8A////AAAAAAAAAAAAAAAAADAAMzMzMzMzMDMzMwMzGAMzMzMzMzMwABEIAf8AAAAzMzMzMzMwADIzMxERERMzMxERERGAADMzMwAAAIAzMzMzMzMzPzMzMwAAADAAADNGMzMzM0JNegAAAAAAABN2AAAAKAAAACAOAAAgFgAAAQAEAAIAAAAAfxYAEgsAABILAAAAABp/VLge/AAA/+D6AAAAAP8AAP//AP///wAAAAAwAAMzMzMzIgOPMzMzOxCA/42NjY2NjY2NjY0zM0EcMzLgMzAzMzMzMzMzMzMzMzMfAAAREREz/xE2MzczMzwWMzMAAACAMzMzLzMzMz8zMzMAAAAwAAAzRkZGRkYzMzAzMwkDMzMwSjMzMxEzMzMwABERAR4EADPyMzMzMzMwFhYWLQAAAIAzERYGFhYWFhYWVhYWFhYWFhYWFhYWFhYWFhYWFhsWAxYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYzM0EcMzLgMzAzMzMWFhYWFhYW//8AAAMWFhYWFhYWFhEZEREDMzMzMzMzMzMwfzMzM1AzMAMzMzQgAAAAEQMzMzMwFwAIAIMzMzMeYRAcMzLgMzAzMzMzAzL4MzMzMzPoAzMzMzMv+i/uMzMzMzM='>
+<img id='m2' height='2' width='2'>
+<canvas id='c1'></canvas>
+<script>
+ var im1=document.getElementById('m1');
+ var im2=document.getElementById('m2');
+ im2.src=im1.src;
+ window.onload=function(){
+ var ctx=document.getElementById('c1').getContext('2d');
+ ctx.drawImage(im1, 0, 0);
+ ctx.drawImage(im2, 0, 0);
+ }
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/image/test/crashtests/1241729-1.bmp b/image/test/crashtests/1241729-1.bmp
new file mode 100644
index 0000000000..e6f36d0398
--- /dev/null
+++ b/image/test/crashtests/1241729-1.bmp
Binary files differ
diff --git a/image/test/crashtests/1241729-1.html b/image/test/crashtests/1241729-1.html
new file mode 100644
index 0000000000..47f23134b4
--- /dev/null
+++ b/image/test/crashtests/1241729-1.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<img src="1241729-1.bmp" style="width: 10px; height: 10px;">
+</body>
+</html>
diff --git a/image/test/crashtests/1242093-1.html b/image/test/crashtests/1242093-1.html
new file mode 100644
index 0000000000..3eab166efd
--- /dev/null
+++ b/image/test/crashtests/1242093-1.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='UTF-8'>
+<meta http-equiv='Cache-control' content='no-cache'>
+</head>
+<body>
+<img id='m1' src='data:image/bmp;base64,Qk1mDgAAAAAAAHYAAAAoAAAAQAEAAPAAAAABAAQAAgAAAPANAADoAwAA6AMAABAAAAAAAAAA/wD/AAAAAAAAAP8AAP8AAP8AAAD///8AzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAAACAAEAAgABAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAAAAAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRCAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBpRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAIAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICAGgiAAJqAGpEAAAAAgIAaCIAAmoAakQAAAACAgBoIgACagBqRAAAAAICADgRMCIAAmoAakQAAAACAgA4ETAiAAJqAGpEAAAAAgIABhEBVQURA1UDEQFVCREEVQIRBFUCEQFVCBEBVQYRMCIAAmoAakQAAAACAgAGEQFVBBEBVQMRAVUCEQFVCREBVQURAVUFEQFVCBEBVQYRMCIAAmoAakQAAAACAgAGEQFVBBEBVQMRAVUCEQFVCREBVQURAVUFEQFVCBEBVQYRMCIAAmoAakQAAAACAgAGEQFVBBEBVQMRAVUCEQRVBhEBVQURA1UDEQNVBhEBVQYRMCIAAmoAakQAAAACAgAGEQFVBBEBVQMRAVUCEQFVAxEBVQURAVUFEQFVBREBVQgRAVUGETAiAAJqAGpEAAAAAgIABhEBVQQRAVUDEQFVAhEBVQMRAVUFEQFVBREBVQURAVUIEQFVBhEwIgACagBqRAAAAAICAAMRB1UCEQNVAxEEVQYRAVUFEQRVAhEEVQIRB1UDETAiAAJqAGpEAAAAAgIAOBEwIgACagBqRAAAAAICADgRMCIAAmoAakQAAAACAAEAAgABAAE='>
+<img id='m2' height='2' width='2'>
+<canvas id='c1'></canvas>
+<script>
+ var im1=document.getElementById('m1');
+ var im2=document.getElementById('m2');
+ im2.src=im1.src;
+ window.onload=function(){
+ var ctx=document.getElementById('c1').getContext('2d');
+ ctx.drawImage(im1, 0, 0); // sync docoder call
+ ctx.drawImage(im2, 0, 0); // sync downscaler call
+ }
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/image/test/crashtests/1242778-1.png b/image/test/crashtests/1242778-1.png
new file mode 100644
index 0000000000..4504d54e45
--- /dev/null
+++ b/image/test/crashtests/1242778-1.png
Binary files differ
diff --git a/image/test/crashtests/1249576-1.png b/image/test/crashtests/1249576-1.png
new file mode 100644
index 0000000000..637dafbc2b
--- /dev/null
+++ b/image/test/crashtests/1249576-1.png
Binary files differ
diff --git a/image/test/crashtests/1251091-1.html b/image/test/crashtests/1251091-1.html
new file mode 100644
index 0000000000..520a393b43
--- /dev/null
+++ b/image/test/crashtests/1251091-1.html
@@ -0,0 +1,51 @@
+<!doctype html>
+<html class="reftest-wait">
+ <head>
+ <script type="text/javascript">
+var gl;
+
+function start() {
+ var canvas = document.getElementById("glcanvas");
+ gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
+
+ if (gl) {
+ initTextures();
+ } else {
+ finish();
+ }
+}
+
+function initTextures() {
+ var cubeTexture = gl.createTexture();
+ var cubeImage = document.getElementById("i");
+ cubeImage.onload = function() { handleTextureLoaded(cubeImage, cubeTexture); }
+ cubeImage.onerror = function() { finish(); }
+ cubeImage.src = "1251091-1.png";
+}
+
+function handleTextureLoaded(image, texture) {
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ setTimeout(showit,0);
+}
+
+function showit() {
+ document.getElementById("i").style.display = "";
+ finish();
+}
+
+function finish() {
+ document.documentElement.removeAttribute("class");
+}
+ </script>
+ </head>
+
+ <body onload="start()">
+ <canvas id="glcanvas" width="640" height="480"></canvas>
+ <img id="i" style="display: none;">
+ </body>
+</html> \ No newline at end of file
diff --git a/image/test/crashtests/1251091-1.png b/image/test/crashtests/1251091-1.png
new file mode 100644
index 0000000000..078b19a569
--- /dev/null
+++ b/image/test/crashtests/1251091-1.png
Binary files differ
diff --git a/image/test/crashtests/1253362-1.html b/image/test/crashtests/1253362-1.html
new file mode 100644
index 0000000000..fdee850aab
--- /dev/null
+++ b/image/test/crashtests/1253362-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+</head>
+<body>
+
+<div style="content: url(data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20style%3D%22background%3A%20url%28data%3Aimage%2Fsvg%2Bxml%2C%253Csvg%2520xmlns%253D%2522http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg%2522%253E%253C%252Fsvg%253E%29%22%3E%3C%2Fsvg%3E%0D%0A)"></div>
+
+</body>
+</html>
diff --git a/image/test/crashtests/1262549-1.gif b/image/test/crashtests/1262549-1.gif
new file mode 100644
index 0000000000..7cb2e769d2
--- /dev/null
+++ b/image/test/crashtests/1262549-1.gif
Binary files differ
diff --git a/image/test/crashtests/1277397-1.jpg b/image/test/crashtests/1277397-1.jpg
new file mode 100644
index 0000000000..54f21182b6
--- /dev/null
+++ b/image/test/crashtests/1277397-1.jpg
Binary files differ
diff --git a/image/test/crashtests/1277397-2.jpg b/image/test/crashtests/1277397-2.jpg
new file mode 100644
index 0000000000..f9fc8744e8
--- /dev/null
+++ b/image/test/crashtests/1277397-2.jpg
Binary files differ
diff --git a/image/test/crashtests/1355898-1.html b/image/test/crashtests/1355898-1.html
new file mode 100644
index 0000000000..2df55b34ac
--- /dev/null
+++ b/image/test/crashtests/1355898-1.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<html>
+ <head>
+ <script>
+// Test that texImage2D on an animated image doesn't assert.
+
+var gl;
+
+function start() {
+ canvas = document.getElementById("glcanvas");
+ gl = null;
+
+ try {
+ gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
+ }
+ catch(e) {
+ }
+
+ if (!gl) {
+ return;
+ }
+
+ var texture = gl.createTexture();
+ var image = new Image();
+ image.onload = function() { handleTextureLoaded(image, texture); }
+ image.src = "1249576-1.png"; // an animated png
+}
+
+function handleTextureLoaded(image, texture) {
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+}
+ </script>
+ </head>
+
+ <body onload="start()">
+ <canvas id="glcanvas" width="640" height="480">
+ Your browser doesn't appear to support the <code>&lt;canvas&gt;</code> element.
+ </canvas>
+ </body>
+</html> \ No newline at end of file
diff --git a/image/test/crashtests/1375842-1.html b/image/test/crashtests/1375842-1.html
new file mode 100644
index 0000000000..457966a1b9
--- /dev/null
+++ b/image/test/crashtests/1375842-1.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<style>
+textarea {
+ border: red;
+ transform: rotate(-0.01rad);
+}
+</style>
+</head>
+<body>
+<textarea></textarea>
+</body>
+</html>
+
diff --git a/image/test/crashtests/1413762-1.gif b/image/test/crashtests/1413762-1.gif
new file mode 100644
index 0000000000..5dd10b8f25
--- /dev/null
+++ b/image/test/crashtests/1413762-1.gif
Binary files differ
diff --git a/image/test/crashtests/1443232-1.gif b/image/test/crashtests/1443232-1.gif
new file mode 100644
index 0000000000..198519e7c0
--- /dev/null
+++ b/image/test/crashtests/1443232-1.gif
Binary files differ
diff --git a/image/test/crashtests/1443232-1.html b/image/test/crashtests/1443232-1.html
new file mode 100644
index 0000000000..a7302e9e16
--- /dev/null
+++ b/image/test/crashtests/1443232-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<body>
+<img id='m1'><br/>
+<script>
+ var im1=document.getElementById('m1');
+ var step_state=0;
+ function handle_step(){
+ step_state+=1;
+ if(step_state == 1){
+ im1.src='data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACwAAAAAAQABAAACAkQBADs=';
+ }
+ else if(step_state==2){
+ im1.src='1443232-1.gif';
+ }
+ else if(step_state==3){
+ if(im1.height==2)
+ im1.height=1;
+ im1.height=2;
+ im1.getBoundingClientRect();
+ setTimeout(function(){document.documentElement.classList.remove("reftest-wait");}, 1000);
+ }
+ }
+ document.addEventListener('DOMContentLoaded', function(){
+ im1.addEventListener('load', handle_step, false);
+ im1.src='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
+ });
+</script>
+</body>
+</html>
diff --git a/image/test/crashtests/1509998.gif b/image/test/crashtests/1509998.gif
new file mode 100644
index 0000000000..05b141ba5f
--- /dev/null
+++ b/image/test/crashtests/1509998.gif
Binary files differ
diff --git a/image/test/crashtests/1526717-1.html b/image/test/crashtests/1526717-1.html
new file mode 100644
index 0000000000..b120340416
--- /dev/null
+++ b/image/test/crashtests/1526717-1.html
@@ -0,0 +1 @@
+<img height="64" width="64" src="fuzz-1311.png?0.5592939664601271"> \ No newline at end of file
diff --git a/image/test/crashtests/1526717-1.png b/image/test/crashtests/1526717-1.png
new file mode 100644
index 0000000000..5ac5b32744
--- /dev/null
+++ b/image/test/crashtests/1526717-1.png
Binary files differ
diff --git a/image/test/crashtests/1629490-1-iframe.html b/image/test/crashtests/1629490-1-iframe.html
new file mode 100644
index 0000000000..2d20e28eed
--- /dev/null
+++ b/image/test/crashtests/1629490-1-iframe.html
@@ -0,0 +1 @@
+<img id="image1" src="finite-apng.png">
diff --git a/image/test/crashtests/1629490-1.html b/image/test/crashtests/1629490-1.html
new file mode 100644
index 0000000000..f35568ca4e
--- /dev/null
+++ b/image/test/crashtests/1629490-1.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+</head>
+<body>
+<div id="container">
+ <iframe id='if' src="1629490-1-iframe.html"></iframe>
+</div>
+
+<script>
+let iterationsLeft = 25;
+
+function runTest() {
+ // Make sure the image is decoded and advanced to it's final frame.
+ let img = document.getElementById("if").contentWindow.document.getElementById("image1");
+ img.decode().then(function() {
+ setTimeout(forceDiscard, 2000);
+ });
+}
+
+function showIframe() {
+ document.getElementById("container").style.display = "";
+ document.documentElement.getBoundingClientRect();
+ requestAnimationFrame(forceDecode);
+}
+
+function forceDecode() {
+ let img = document.getElementById("if").contentWindow.document.getElementById("image1");
+ img.decode().then(function() {
+ setTimeout(forceDiscard, 0);
+ });
+}
+
+function forceDiscard() {
+ iterationsLeft--;
+ if (iterationsLeft < 0) {
+ document.documentElement.className = "";
+ return;
+ }
+ document.getElementById("container").style.display = "none";
+ document.documentElement.getBoundingClientRect();
+ requestAnimationFrame(() => { requestAnimationFrame( () => { setTimeout(showIframe, 0); } ) });
+}
+
+//window.addEventListener("load", runTest);
+window.addEventListener("MozReftestInvalidate", runTest);
+</script>
+</body>
+</html>
diff --git a/image/test/crashtests/1634839-1-iframe.html b/image/test/crashtests/1634839-1-iframe.html
new file mode 100644
index 0000000000..07c1b6545e
--- /dev/null
+++ b/image/test/crashtests/1634839-1-iframe.html
@@ -0,0 +1 @@
+<img id="image1" src="rainbow.gif">
diff --git a/image/test/crashtests/1634839-1.html b/image/test/crashtests/1634839-1.html
new file mode 100644
index 0000000000..865f83645f
--- /dev/null
+++ b/image/test/crashtests/1634839-1.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+</head>
+<body>
+<div id="container">
+ <iframe id='if' src="1634839-1-iframe.html"></iframe>
+</div>
+
+<script>
+let iterationsLeft = 1;
+
+let img = null;
+
+function runTest() {
+ // Make sure the image is decoded and advanced to it's final frame.
+ img = document.getElementById("if").contentWindow.document.getElementById("image1");
+ img.decode().then(function() {
+ setTimeout(forceDiscard, 200);
+ });
+}
+
+function showIframe() {
+ document.getElementById("container").style.display = "";
+ document.documentElement.getBoundingClientRect();
+ requestAnimationFrame(forceDecode);
+}
+
+function forceDecode() {
+ img.decode().then(function() {
+ setTimeout(forceDiscard, 0);
+ });
+}
+
+function forceDiscard() {
+ iterationsLeft--;
+ if (iterationsLeft < 0) {
+ document.documentElement.className = "";
+ return;
+ }
+ document.getElementById("container").style.display = "none";
+ document.documentElement.getBoundingClientRect();
+ img.remove();
+ requestAnimationFrame(() => { requestAnimationFrame( () => { setTimeout(showIframe, 0); } ) });
+}
+
+//window.addEventListener("load", runTest);
+window.addEventListener("MozReftestInvalidate", runTest);
+</script>
+</body>
+</html>
diff --git a/image/test/crashtests/1634839-2-iframe.html b/image/test/crashtests/1634839-2-iframe.html
new file mode 100644
index 0000000000..6907844499
--- /dev/null
+++ b/image/test/crashtests/1634839-2-iframe.html
@@ -0,0 +1 @@
+<img id="image1" src="out2.gif">
diff --git a/image/test/crashtests/1634839-2.html b/image/test/crashtests/1634839-2.html
new file mode 100644
index 0000000000..d3629421fb
--- /dev/null
+++ b/image/test/crashtests/1634839-2.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+</head>
+<body>
+<div id="container">
+ <iframe id='if' src="1634839-2-iframe.html"></iframe>
+</div>
+
+<script>
+let iterationsLeft = 1;
+
+let img = null;
+
+function runTest() {
+ // Make sure the image is decoded and advanced to it's final frame.
+ img = document.getElementById("if").contentWindow.document.getElementById("image1");
+ img.decode().then(function() {
+ setTimeout(forceDiscard, 1000);
+ });
+}
+
+function showIframe() {
+ document.getElementById("container").style.display = "";
+ document.documentElement.getBoundingClientRect();
+ requestAnimationFrame(forceDecode);
+}
+
+function forceDecode() {
+ img.decode().then(function() {
+ setTimeout(forceDiscard, 0);
+ });
+}
+
+function forceDiscard() {
+ iterationsLeft--;
+ if (iterationsLeft < 0) {
+ document.documentElement.className = "";
+ return;
+ }
+ document.getElementById("container").style.display = "none";
+ document.documentElement.getBoundingClientRect();
+ img.remove();
+ requestAnimationFrame(() => { requestAnimationFrame( () => { setTimeout(showIframe, 0); } ) });
+}
+
+//window.addEventListener("load", runTest);
+window.addEventListener("MozReftestInvalidate", runTest);
+</script>
+</body>
+</html>
diff --git a/image/test/crashtests/1676172-1-iframe.html b/image/test/crashtests/1676172-1-iframe.html
new file mode 100644
index 0000000000..c989c579bb
--- /dev/null
+++ b/image/test/crashtests/1676172-1-iframe.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+ <script>
+ document.addEventListener('DOMContentLoaded', () => {
+ const image = document.createElementNS('http://www.w3.org/1999/xhtml', 'img')
+ var extra = document.location.search.substr(1);
+ image.setAttribute('src', '1676172-1.gif' + '?' + extra)
+ document.documentElement.appendChild(image)
+ setTimeout('location.reload()', 400)
+ })
+ </script>
+</head>
+</html>
diff --git a/image/test/crashtests/1676172-1.gif b/image/test/crashtests/1676172-1.gif
new file mode 100644
index 0000000000..c5635218d5
--- /dev/null
+++ b/image/test/crashtests/1676172-1.gif
Binary files differ
diff --git a/image/test/crashtests/1676172-1.html b/image/test/crashtests/1676172-1.html
new file mode 100644
index 0000000000..08374a4772
--- /dev/null
+++ b/image/test/crashtests/1676172-1.html
@@ -0,0 +1,57 @@
+<html class="reftest-wait">
+<head>
+<script>
+function setup() {
+ setTimeout(finish, 1500);
+}
+function finish() {
+ window.stop();
+ document.documentElement.className = "";
+}
+</script>
+<style>
+ iframe {
+ width: 100px;
+ height: 100px;
+ }
+</style>
+</head>
+<body onload="setup();">
+<script>
+let numiframes = 30;
+
+const Cc = SpecialPowers.Cc;
+const Ci = SpecialPowers.Ci;
+let isDebugBuild =
+ Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2).isDebugBuild;
+let isMac =
+ navigator.appVersion.toLowerCase().includes("mac") ||
+ navigator.platform.toLowerCase().includes("mac");
+
+// On some platforms too many animating and reloading gifs means we don't ever
+// get enough time to serve paints so that there is never a period of time
+// where there are no paints pending, so the reftest harness can't end the
+// test. So we limit the number on those platforms, since we only need one
+// iframe to reproduce the bug this is okay, more iframes just give more
+// chance of reproducing it on any given run.
+if (navigator.appVersion.includes("Windows")) {
+ numiframes = 16;
+}
+if (navigator.platform.includes("Linux")) {
+ numiframes = 10;
+}
+if (navigator.appVersion.includes("Android")) {
+ numiframes = 2;
+}
+if (isMac && isDebugBuild) {
+ numiframes = 20;
+}
+for (let i = 0; i < numiframes; i++) {
+ let ifr = document.createElement("iframe");
+ document.body.appendChild(ifr)
+ ifr.src = "1676172-1-iframe.html?" + i;
+}
+setTimeout(finish, 1500);
+</script>
+</body>
+</html>
diff --git a/image/test/crashtests/1763581-1-iframe.html b/image/test/crashtests/1763581-1-iframe.html
new file mode 100644
index 0000000000..6064183b9e
--- /dev/null
+++ b/image/test/crashtests/1763581-1-iframe.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script>
+ window.onload = function() {
+ img = document.querySelector(".animated-image")
+ const staticImage = new Image();
+ staticImage.src = img.src;
+ }
+ </script>
+ </head>
+ <body>
+ <img class="animated-image" src="1763581-1.sjs">
+ </body>
+</html>
diff --git a/image/test/crashtests/1763581-1.gif b/image/test/crashtests/1763581-1.gif
new file mode 100644
index 0000000000..237d6a1722
--- /dev/null
+++ b/image/test/crashtests/1763581-1.gif
Binary files differ
diff --git a/image/test/crashtests/1763581-1.html b/image/test/crashtests/1763581-1.html
new file mode 100644
index 0000000000..167f541a24
--- /dev/null
+++ b/image/test/crashtests/1763581-1.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<script>
+window.onload = function() {
+ setTimeout(step, 500);
+}
+
+var reloads = 5;
+
+function step() {
+ if (--reloads) {
+ document.getElementById("ifr").contentWindow.location.reload();
+ } else {
+ document.documentElement.className = "";
+ }
+}
+
+function settimouestep() {
+ setTimeout(step, 500);
+}
+</script>
+</head>
+<body>
+ <iframe id="ifr" src="1763581-1-iframe.html" height="500" width="400" onload="settimouestep()"></iframe>
+</body>
+</html>
+
diff --git a/image/test/crashtests/1763581-1.sjs b/image/test/crashtests/1763581-1.sjs
new file mode 100644
index 0000000000..9fb70dd463
--- /dev/null
+++ b/image/test/crashtests/1763581-1.sjs
@@ -0,0 +1,71 @@
+
+function getFileStream(filename)
+{
+ // Get the location of this sjs file, and then use that to figure out where
+ // to find where our other files are.
+ var self = Components.classes["@mozilla.org/file/local;1"]
+ .createInstance(Components.interfaces.nsIFile);
+ self.initWithPath(getState("__LOCATION__"));
+ var file = self.parent;
+ file.append(filename);
+
+ var fileStream = Components.classes['@mozilla.org/network/file-input-stream;1']
+ .createInstance(Components.interfaces.nsIFileInputStream);
+ fileStream.init(file, 1, 0, false);
+
+ return fileStream;
+}
+
+// stolen from file_blocked_script.sjs
+function setGlobalState(data, key) {
+ x = {
+ data,
+ QueryInterface: ChromeUtils.generateQI([]),
+ };
+ x.wrappedJSObject = x;
+ setObjectState(key, x);
+}
+
+function getGlobalState(key) {
+ var data;
+ getObjectState(key, function(x) {
+ data = x && x.wrappedJSObject.data;
+ });
+ return data;
+}
+
+const DELAY_MS = 100;
+let gTimer;
+
+function handleRequest(request, response) {
+ let count = getGlobalState("count");
+ if (count == null) {
+ count = 0;
+ }
+
+ if (count > 0) {
+ response.processAsync();
+
+ gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ gTimer.init(
+ () => {
+ response.setStatusLine(request.httpVersion, 304, "Not Modified");
+ response.finish();
+ },
+ DELAY_MS,
+ Ci.nsITimer.TYPE_ONE_SHOT
+ );
+
+ return;
+ }
+
+ response.setStatusLine(request.httpVersion, 200, "OK");
+ response.setHeader("Content-Type", "image/gif", false);
+
+ var inputStream = getFileStream("1763581-1.gif");
+ response.bodyOutputStream.writeFrom(inputStream, inputStream.available());
+ inputStream.close();
+
+ count++;
+ setGlobalState(count, "count");
+}
diff --git a/image/test/crashtests/1765871-1.jpg b/image/test/crashtests/1765871-1.jpg
new file mode 100644
index 0000000000..11460a62c3
--- /dev/null
+++ b/image/test/crashtests/1765871-1.jpg
Binary files differ
diff --git a/image/test/crashtests/1814553.avif b/image/test/crashtests/1814553.avif
new file mode 100644
index 0000000000..7e2f040c53
--- /dev/null
+++ b/image/test/crashtests/1814553.avif
Binary files differ
diff --git a/image/test/crashtests/1814561.avif b/image/test/crashtests/1814561.avif
new file mode 100644
index 0000000000..33ad44d2a3
--- /dev/null
+++ b/image/test/crashtests/1814561.avif
Binary files differ
diff --git a/image/test/crashtests/1814677.avif b/image/test/crashtests/1814677.avif
new file mode 100644
index 0000000000..b91d4f955b
--- /dev/null
+++ b/image/test/crashtests/1814677.avif
Binary files differ
diff --git a/image/test/crashtests/1814708.avif b/image/test/crashtests/1814708.avif
new file mode 100644
index 0000000000..21a39cfa4d
--- /dev/null
+++ b/image/test/crashtests/1814708.avif
Binary files differ
diff --git a/image/test/crashtests/1814741.avif b/image/test/crashtests/1814741.avif
new file mode 100644
index 0000000000..842eaea1c1
--- /dev/null
+++ b/image/test/crashtests/1814741.avif
Binary files differ
diff --git a/image/test/crashtests/1814774.avif b/image/test/crashtests/1814774.avif
new file mode 100644
index 0000000000..77ffba7af2
--- /dev/null
+++ b/image/test/crashtests/1814774.avif
Binary files differ
diff --git a/image/test/crashtests/1817108.avif b/image/test/crashtests/1817108.avif
new file mode 100644
index 0000000000..a06b923ee4
--- /dev/null
+++ b/image/test/crashtests/1817108.avif
Binary files differ
diff --git a/image/test/crashtests/256-height.ico b/image/test/crashtests/256-height.ico
new file mode 100644
index 0000000000..6a3c5c1944
--- /dev/null
+++ b/image/test/crashtests/256-height.ico
Binary files differ
diff --git a/image/test/crashtests/256-width.ico b/image/test/crashtests/256-width.ico
new file mode 100644
index 0000000000..a82983ce4f
--- /dev/null
+++ b/image/test/crashtests/256-width.ico
Binary files differ
diff --git a/image/test/crashtests/463696.bmp b/image/test/crashtests/463696.bmp
new file mode 100644
index 0000000000..ec80d54126
--- /dev/null
+++ b/image/test/crashtests/463696.bmp
Binary files differ
diff --git a/image/test/crashtests/523528-1.gif b/image/test/crashtests/523528-1.gif
new file mode 100644
index 0000000000..abadca7ad2
--- /dev/null
+++ b/image/test/crashtests/523528-1.gif
Binary files differ
diff --git a/image/test/crashtests/523528-2.gif b/image/test/crashtests/523528-2.gif
new file mode 100644
index 0000000000..5be3bd46f6
--- /dev/null
+++ b/image/test/crashtests/523528-2.gif
Binary files differ
diff --git a/image/test/crashtests/570451.png b/image/test/crashtests/570451.png
new file mode 100644
index 0000000000..c49f2d11f1
--- /dev/null
+++ b/image/test/crashtests/570451.png
Binary files differ
diff --git a/image/test/crashtests/694165-1.xhtml b/image/test/crashtests/694165-1.xhtml
new file mode 100644
index 0000000000..1e340a0f2f
--- /dev/null
+++ b/image/test/crashtests/694165-1.xhtml
@@ -0,0 +1,510 @@
+<!DOCTYPE html [
+ <!ENTITY thousand-g-elements "
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+ &lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;&lt;g/&gt;
+">
+
+]>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<img src='data:image/svg+xml,&lt;svg xmlns="http://www.w3.org/2000/svg"&gt;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &thousand-g-elements;
+ &lt;/svg&gt;'/>
+</html>
diff --git a/image/test/crashtests/732319-1.html b/image/test/crashtests/732319-1.html
new file mode 100644
index 0000000000..b9d9c6de87
--- /dev/null
+++ b/image/test/crashtests/732319-1.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<img crossorigin src="data:a/a,">
diff --git a/image/test/crashtests/83804-1.gif b/image/test/crashtests/83804-1.gif
new file mode 100644
index 0000000000..3967c703f6
--- /dev/null
+++ b/image/test/crashtests/83804-1.gif
Binary files differ
diff --git a/image/test/crashtests/844403-1.html b/image/test/crashtests/844403-1.html
new file mode 100644
index 0000000000..ef207c0f9f
--- /dev/null
+++ b/image/test/crashtests/844403-1.html
@@ -0,0 +1,10 @@
+<color style='background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSINCiAgICAgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiPg0KICA8cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJibHVlIi8%2BDQo8L3N2Zz4NCg%3D%3D");'></color>
+<iframe contenteditable=true></iframe>
+<script>
+ document.body.innerHTML = '';
+ function onload() {
+ e = document.createElementNS("http://www.w3.org/1998/Math/MathML", "share");
+ document.body.appendChild(e);
+ }
+ document.addEventListener("DOMContentLoaded", onload);
+</script>
diff --git a/image/test/crashtests/856616.gif b/image/test/crashtests/856616.gif
new file mode 100644
index 0000000000..0fac811014
--- /dev/null
+++ b/image/test/crashtests/856616.gif
Binary files differ
diff --git a/image/test/crashtests/89341-1.gif b/image/test/crashtests/89341-1.gif
new file mode 100644
index 0000000000..14b3892d17
--- /dev/null
+++ b/image/test/crashtests/89341-1.gif
Binary files differ
diff --git a/image/test/crashtests/944353.jpg b/image/test/crashtests/944353.jpg
new file mode 100644
index 0000000000..fd81c58263
--- /dev/null
+++ b/image/test/crashtests/944353.jpg
Binary files differ
diff --git a/image/test/crashtests/colormap-range.gif b/image/test/crashtests/colormap-range.gif
new file mode 100644
index 0000000000..887add653f
--- /dev/null
+++ b/image/test/crashtests/colormap-range.gif
Binary files differ
diff --git a/image/test/crashtests/crashtests.list b/image/test/crashtests/crashtests.list
new file mode 100644
index 0000000000..055ad677a1
--- /dev/null
+++ b/image/test/crashtests/crashtests.list
@@ -0,0 +1,84 @@
+# Bug 668068 - Maximum (256) width and height icons that we currently interpret as 0-width and 0-height.
+load 256-height.ico
+load 256-width.ico
+
+load 83804-1.gif
+load 89341-1.gif
+load 463696.bmp
+load 570451.png
+# Bug 1390704 - Skip on debug because it triggers a quadratic behavior that makes it take
+# so much time that it can trip on the reftest timeout of 5 minutes.
+skip-if(Android||isDebugBuild||ThreadSanitizer) load 694165-1.xhtml
+load 732319-1.html
+load 844403-1.html
+load 856616.gif
+skip-if(ThreadSanitizer) load 944353.jpg
+load 1205923-1.html
+# Ensure we handle detecting that an image is animated, then failing to decode
+# it. (See bug 1210745.)
+load 1210745-1.gif
+load 1212954-1.svg
+load 1235605.gif
+load 1241728-1.html
+load 1241729-1.html
+load 1242093-1.html
+skip-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&/^aarch64-msvc/.test(xulRuntime.XPCOMABI)) load 1242778-1.png
+load 1249576-1.png
+load 1253362-1.html
+skip-if(Android&&browserIsRemote) load 1355898-1.html # bug 1507207
+load 1375842-1.html
+load 1413762-1.gif
+pref(image.downscale-during-decode.enabled,true) load 1443232-1.html
+load colormap-range.gif
+HTTP load delayedframe.sjs # A 3-frame animated GIF with an inordinate delay between the second and third frame
+
+# Animated gifs with a very large canvas, but tiny actual content.
+load delaytest.html?523528-1.gif
+load delaytest.html?523528-2.gif
+
+load delaytest.html?1262549-1.gif
+load delaytest.html?1277397-1.jpg
+load delaytest.html?1277397-2.jpg
+
+# Bug 1160801 - Ensure that we handle invalid disposal types.
+load invalid-disposal-method-1.gif
+load invalid-disposal-method-2.gif
+load invalid-disposal-method-3.gif
+
+load invalid-icc-profile.jpg # This would have exposed the leak discovered in bug 642902
+
+# Ensure we handle ICO directory entries which specify the wrong size for the contained resource.
+load invalid_ico_height.ico
+load invalid_ico_width.ico
+
+# Bug 525326 - Test image sizes of 65535x65535 which is larger than we allow)
+load invalid-size.gif
+load invalid-size-second-frame.gif
+
+load multiple-png-hassize.ico # Bug 863958 - This icon's size is such that it leads to multiple writes to the PNG decoder after we've gotten our size.
+skip-if(ThreadSanitizer) asserts(0-2) load ownerdiscard.html # Bug 1323672, bug 807211
+load truncated-second-frame.png # Bug 863975
+
+# Bug 1509998 - Ensure that we handle empty frame rects in animated images.
+load 1509998.gif
+
+load 1526717-1.html
+skip-if(ThreadSanitizer) pref(widget.windows.window_occlusion_tracking.enabled,false) load 1629490-1.html # Bug 1819154
+
+pref(widget.windows.window_occlusion_tracking.enabled,false) HTTP load 1634839-1.html # Bug 1819154
+pref(widget.windows.window_occlusion_tracking.enabled,false) HTTP load 1634839-2.html # Bug 1819154
+pref(image.animated.decode-on-demand.batch-size,1) pref(image.animated.decode-on-demand.threshold-kb,0) HTTP load 1676172-1.html
+pref(browser.soft_reload.only_force_validate_top_level_document,false) HTTP load 1763581-1.html
+load 1765871-1.jpg
+
+load 1814561.avif
+load 1814708.avif
+
+load 1814553.avif
+
+load 1814677.avif
+
+load 1814741.avif
+
+load 1814774.avif
+load 1817108.avif
diff --git a/image/test/crashtests/delayedframe.sjs b/image/test/crashtests/delayedframe.sjs
new file mode 100644
index 0000000000..0cd7ce97e9
--- /dev/null
+++ b/image/test/crashtests/delayedframe.sjs
@@ -0,0 +1,44 @@
+function getFileStream(filename)
+{
+ // Get the location of this sjs file, and then use that to figure out where
+ // to find where our other files are.
+ var self = Components.classes["@mozilla.org/file/local;1"]
+ .createInstance(Components.interfaces.nsIFile);
+ self.initWithPath(getState("__LOCATION__"));
+ var file = self.parent;
+ file.append(filename);
+ dump(file.path + "\n");
+
+ var fileStream = Components.classes['@mozilla.org/network/file-input-stream;1']
+ .createInstance(Components.interfaces.nsIFileInputStream);
+ fileStream.init(file, 1, 0, false);
+
+ return fileStream;
+}
+
+var gTimer;
+
+function handleRequest(request, response)
+{
+ response.processAsync();
+ response.setStatusLine(request.httpVersion, 200, "OK");
+ response.setHeader("Content-Type", "image/gif", false);
+
+ var firststream = getFileStream("threeframes-start.gif");
+ response.bodyOutputStream.writeFrom(firststream, firststream.available())
+ firststream.close();
+
+ gTimer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
+ gTimer.initWithCallback(function()
+ {
+ var secondstream = getFileStream("threeframes-end.gif");
+ response.bodyOutputStream.writeFrom(secondstream, secondstream.available())
+ secondstream.close();
+ response.finish();
+
+ // This time needs to be longer than the animation timer in
+ // threeframes-start.gif. That's specified as 100ms; just use 5 seconds as
+ // a reasonable upper bound. Since this is just a crashtest, timeouts
+ // aren't a big deal.
+ }, 5 * 1000 /* milliseconds */, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
+}
diff --git a/image/test/crashtests/delaytest.html b/image/test/crashtests/delaytest.html
new file mode 100644
index 0000000000..fb368c1e90
--- /dev/null
+++ b/image/test/crashtests/delaytest.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Delayed image reftest wrapper</title>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img id="image1" alt=" ">
+<script>
+
+window.addEventListener("MozReftestInvalidate", reftestInvalidateListener);
+
+// This loads a externally specified image, forces a draw (in case of
+// decode-on-draw), waits 350ms, and then triggers the reftest snapshot.
+// This allows the animation on the page to complete.
+//
+// Use as "delaytest.html?animation.png"
+//
+
+// Get the image URL from our URL
+var imgURL = document.location.search.substr(1);
+
+// Load the image
+var img = document.images[0];
+img.src = imgURL;
+img.onload = forceDecode;
+img.onerror = forceDecode;
+
+let decodeComplete = false;
+let gotReftestInvalidate = false;
+
+function forceDecode() {
+ img.decode().then(function() {
+ decodeComplete = true;
+ maybeStartTimer();
+ }, function() {
+ decodeComplete = true;
+ maybeStartTimer();
+ });
+}
+
+function reftestInvalidateListener() {
+ gotReftestInvalidate = true;
+ maybeStartTimer();
+}
+
+function maybeStartTimer() {
+ if (decodeComplete && gotReftestInvalidate) {
+ startTimer();
+ }
+}
+
+function startTimer() {
+ const delay = 350;
+ setTimeout("document.documentElement.className = '';", delay);
+}
+</script>
+</body>
+</html>
diff --git a/image/test/crashtests/discardframe.htm b/image/test/crashtests/discardframe.htm
new file mode 100644
index 0000000000..5ced0029c5
--- /dev/null
+++ b/image/test/crashtests/discardframe.htm
@@ -0,0 +1 @@
+<img src=ie.png>
diff --git a/image/test/crashtests/finite-apng.png b/image/test/crashtests/finite-apng.png
new file mode 100644
index 0000000000..778613d851
--- /dev/null
+++ b/image/test/crashtests/finite-apng.png
Binary files differ
diff --git a/image/test/crashtests/ie.png b/image/test/crashtests/ie.png
new file mode 100644
index 0000000000..74c4a1a323
--- /dev/null
+++ b/image/test/crashtests/ie.png
Binary files differ
diff --git a/image/test/crashtests/invalid-disposal-method-1.gif b/image/test/crashtests/invalid-disposal-method-1.gif
new file mode 100644
index 0000000000..30c61de188
--- /dev/null
+++ b/image/test/crashtests/invalid-disposal-method-1.gif
Binary files differ
diff --git a/image/test/crashtests/invalid-disposal-method-2.gif b/image/test/crashtests/invalid-disposal-method-2.gif
new file mode 100644
index 0000000000..66158d81a9
--- /dev/null
+++ b/image/test/crashtests/invalid-disposal-method-2.gif
Binary files differ
diff --git a/image/test/crashtests/invalid-disposal-method-3.gif b/image/test/crashtests/invalid-disposal-method-3.gif
new file mode 100644
index 0000000000..0da0723773
--- /dev/null
+++ b/image/test/crashtests/invalid-disposal-method-3.gif
Binary files differ
diff --git a/image/test/crashtests/invalid-icc-profile.jpg b/image/test/crashtests/invalid-icc-profile.jpg
new file mode 100644
index 0000000000..938c7713ce
--- /dev/null
+++ b/image/test/crashtests/invalid-icc-profile.jpg
Binary files differ
diff --git a/image/test/crashtests/invalid-size-second-frame.gif b/image/test/crashtests/invalid-size-second-frame.gif
new file mode 100644
index 0000000000..22005ae4ca
--- /dev/null
+++ b/image/test/crashtests/invalid-size-second-frame.gif
Binary files differ
diff --git a/image/test/crashtests/invalid-size.gif b/image/test/crashtests/invalid-size.gif
new file mode 100644
index 0000000000..665ca9b5dc
--- /dev/null
+++ b/image/test/crashtests/invalid-size.gif
Binary files differ
diff --git a/image/test/crashtests/invalid_ico_height.ico b/image/test/crashtests/invalid_ico_height.ico
new file mode 100644
index 0000000000..50d6842278
--- /dev/null
+++ b/image/test/crashtests/invalid_ico_height.ico
Binary files differ
diff --git a/image/test/crashtests/invalid_ico_width.ico b/image/test/crashtests/invalid_ico_width.ico
new file mode 100644
index 0000000000..4ace07c16f
--- /dev/null
+++ b/image/test/crashtests/invalid_ico_width.ico
Binary files differ
diff --git a/image/test/crashtests/multiple-png-hassize.ico b/image/test/crashtests/multiple-png-hassize.ico
new file mode 100644
index 0000000000..6944220018
--- /dev/null
+++ b/image/test/crashtests/multiple-png-hassize.ico
Binary files differ
diff --git a/image/test/crashtests/out2.gif b/image/test/crashtests/out2.gif
new file mode 100644
index 0000000000..f062c7f20c
--- /dev/null
+++ b/image/test/crashtests/out2.gif
Binary files differ
diff --git a/image/test/crashtests/ownerdiscard.html b/image/test/crashtests/ownerdiscard.html
new file mode 100644
index 0000000000..2e5be86023
--- /dev/null
+++ b/image/test/crashtests/ownerdiscard.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<body>
+ <div id=tCF0>
+ <img id=victim src=ie.png>
+ <iframe src=discardframe.htm></iframe>
+ </div>
+ <script>
+ const Ci = SpecialPowers.Ci;
+ const Cc = SpecialPowers.Cc;
+
+ function ImageDecoderObserverStub()
+ {
+ this.sizeAvailable = function sizeAvailable(aRequest) {}
+ this.frameComplete = function frameComplete(aRequest) {}
+ this.decodeComplete = function decodeComplete(aRequest) {}
+ this.loadComplete = function loadComplete(aRequest) {}
+ this.frameUpdate = function frameUpdate(aRequest) {}
+ this.discard = function discard(aRequest) {}
+ this.isAnimated = function isAnimated(aRequest) {}
+ }
+ var img = document.getElementById('victim');
+ var observer = new ImageDecoderObserverStub();
+ observer.discard = function() {
+ cleanupAndFinish();
+ }
+ observer = SpecialPowers.wrapCallbackObject(observer);
+ var gObserver = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
+ .createScriptedObserver(observer);
+ var imgLoadingContent = SpecialPowers.wrap(img);
+ imgLoadingContent.addObserver(gObserver);
+ function initCF() {
+ setTimeout(function() { document.adoptNode(tCF0); }, 0);
+ }
+ document.addEventListener("DOMContentLoaded", initCF);
+
+ function cleanupAndFinish() {
+ imgLoadingContent.removeObserver(gObserver);
+ setTimeout("document.documentElement.className = '';", 0);
+ }
+ function loadhandler() {
+ setTimeout("cleanupAndFinish();", 30000);
+ }
+ window.addEventListener("load", function() {
+ SpecialPowers.pushPrefEnv({"set":[["min_discard_timeout_ms", 1]]}, loadhandler)});
+ </script>
+</body>
+</html>
diff --git a/image/test/crashtests/rainbow.gif b/image/test/crashtests/rainbow.gif
new file mode 100644
index 0000000000..72a7816928
--- /dev/null
+++ b/image/test/crashtests/rainbow.gif
Binary files differ
diff --git a/image/test/crashtests/threeframes-end.gif b/image/test/crashtests/threeframes-end.gif
new file mode 100644
index 0000000000..baf6a418c2
--- /dev/null
+++ b/image/test/crashtests/threeframes-end.gif
Binary files differ
diff --git a/image/test/crashtests/threeframes-start.gif b/image/test/crashtests/threeframes-start.gif
new file mode 100644
index 0000000000..bc641a3166
--- /dev/null
+++ b/image/test/crashtests/threeframes-start.gif
Binary files differ
diff --git a/image/test/crashtests/truncated-second-frame.png b/image/test/crashtests/truncated-second-frame.png
new file mode 100644
index 0000000000..0aef5e44de
--- /dev/null
+++ b/image/test/crashtests/truncated-second-frame.png
Binary files differ
diff --git a/image/test/crashtests/unsized-svg.svg b/image/test/crashtests/unsized-svg.svg
new file mode 100644
index 0000000000..714efc7ef0
--- /dev/null
+++ b/image/test/crashtests/unsized-svg.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg"></svg>
diff --git a/image/test/fuzzing/TestDecoders.cpp b/image/test/fuzzing/TestDecoders.cpp
new file mode 100644
index 0000000000..8515ff43c6
--- /dev/null
+++ b/image/test/fuzzing/TestDecoders.cpp
@@ -0,0 +1,180 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "Common.h"
+#include "imgIContainer.h"
+#include "imgITools.h"
+#include "ImageOps.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/Preferences.h"
+#include "nsComponentManagerUtils.h"
+#include "nsCOMPtr.h"
+#include "nsIInputStream.h"
+#include "nsIRunnable.h"
+#include "nsIThread.h"
+#include "mozilla/RefPtr.h"
+#include "nsString.h"
+#include "nsThreadUtils.h"
+
+#include "FuzzingInterfaceStream.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+// Prevents x being optimized away if it has no side-effects.
+// If optimized away, tools like ASan wouldn't be able to detect
+// faulty memory accesses.
+#define DUMMY_IF(x) \
+ if (x) { \
+ volatile int v; \
+ v = 0; \
+ (void)v; \
+ }
+
+class DecodeToSurfaceRunnableFuzzing : public Runnable {
+ public:
+ DecodeToSurfaceRunnableFuzzing(RefPtr<SourceSurface>& aSurface,
+ nsIInputStream* aInputStream,
+ const char* mimeType)
+ : mozilla::Runnable("DecodeToSurfaceRunnableFuzzing"),
+ mSurface(aSurface),
+ mInputStream(aInputStream),
+ mMimeType(mimeType) {}
+
+ NS_IMETHOD Run() override {
+ Go();
+ return NS_OK;
+ }
+
+ void Go() {
+ mSurface = ImageOps::DecodeToSurface(mInputStream.forget(), mMimeType,
+ imgIContainer::DECODE_FLAGS_DEFAULT);
+ if (!mSurface) return;
+
+ if (mSurface->GetType() == SurfaceType::DATA) {
+ if (mSurface->GetFormat() == SurfaceFormat::OS_RGBX ||
+ mSurface->GetFormat() == SurfaceFormat::OS_RGBA) {
+ DUMMY_IF(IntSize(1, 1) == mSurface->GetSize());
+ DUMMY_IF(IsSolidColor(mSurface, BGRAColor::Green(), 1));
+ }
+ }
+ }
+
+ private:
+ RefPtr<SourceSurface>& mSurface;
+ nsCOMPtr<nsIInputStream> mInputStream;
+ nsAutoCString mMimeType;
+};
+
+static int RunDecodeToSurfaceFuzzing(nsCOMPtr<nsIInputStream> inputStream,
+ const char* mimeType) {
+ uint64_t len;
+ inputStream->Available(&len);
+ if (len <= 0) {
+ return 0;
+ }
+
+ // Ensure CMS state is initialized on the main thread.
+ gfxPlatform::GetCMSMode();
+
+ nsCOMPtr<nsIThread> thread;
+ nsresult rv =
+ NS_NewNamedThread("Decoder Test", getter_AddRefs(thread), nullptr);
+ MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
+
+ // We run the DecodeToSurface tests off-main-thread to ensure that
+ // DecodeToSurface doesn't require any other main-thread-only code.
+ RefPtr<SourceSurface> surface;
+ nsCOMPtr<nsIRunnable> runnable =
+ new DecodeToSurfaceRunnableFuzzing(surface, inputStream, mimeType);
+ NS_DispatchAndSpinEventLoopUntilComplete("RunDecodeToSurfaceFuzzing"_ns,
+ thread, runnable.forget());
+
+ thread->Shutdown();
+
+ // Explicitly release the SourceSurface on the main thread.
+ surface = nullptr;
+
+ return 0;
+}
+
+static int RunDecodeToSurfaceFuzzingJPEG(nsCOMPtr<nsIInputStream> inputStream) {
+ return RunDecodeToSurfaceFuzzing(inputStream, "image/jpeg");
+}
+
+static int RunDecodeToSurfaceFuzzingGIF(nsCOMPtr<nsIInputStream> inputStream) {
+ return RunDecodeToSurfaceFuzzing(inputStream, "image/gif");
+}
+
+static int RunDecodeToSurfaceFuzzingICO(nsCOMPtr<nsIInputStream> inputStream) {
+ return RunDecodeToSurfaceFuzzing(inputStream, "image/ico");
+}
+
+static int RunDecodeToSurfaceFuzzingBMP(nsCOMPtr<nsIInputStream> inputStream) {
+ return RunDecodeToSurfaceFuzzing(inputStream, "image/bmp");
+}
+
+static int RunDecodeToSurfaceFuzzingPNG(nsCOMPtr<nsIInputStream> inputStream) {
+ return RunDecodeToSurfaceFuzzing(inputStream, "image/png");
+}
+
+static int RunDecodeToSurfaceFuzzingWebP(nsCOMPtr<nsIInputStream> inputStream) {
+ return RunDecodeToSurfaceFuzzing(inputStream, "image/webp");
+}
+
+static int RunDecodeToSurfaceFuzzingAVIF(nsCOMPtr<nsIInputStream> inputStream) {
+ return RunDecodeToSurfaceFuzzing(inputStream, "image/avif");
+}
+
+#ifdef MOZ_JXL
+static int RunDecodeToSurfaceFuzzingJXL(nsCOMPtr<nsIInputStream> inputStream) {
+ return RunDecodeToSurfaceFuzzing(inputStream, "image/jxl");
+}
+#endif
+
+int FuzzingInitImage(int* argc, char*** argv) {
+ Preferences::SetBool("image.avif.sequence.enabled", true);
+#ifdef MOZ_JXL
+ Preferences::SetBool("image.jxl.enabled", true);
+#endif
+
+ nsCOMPtr<imgITools> imgTools =
+ do_CreateInstance("@mozilla.org/image/tools;1");
+ if (imgTools == nullptr) {
+ std::cerr << "Initializing image tools failed" << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
+
+MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingJPEG,
+ ImageJPEG);
+
+MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingGIF,
+ ImageGIF);
+
+MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingICO,
+ ImageICO);
+
+MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingBMP,
+ ImageBMP);
+
+MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingPNG,
+ ImagePNG);
+
+MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingWebP,
+ ImageWebP);
+
+MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingAVIF,
+ ImageAVIF);
+
+#ifdef MOZ_JXL
+MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingJXL,
+ ImageJXL);
+#endif
diff --git a/image/test/fuzzing/moz.build b/image/test/fuzzing/moz.build
new file mode 100644
index 0000000000..24af56396f
--- /dev/null
+++ b/image/test/fuzzing/moz.build
@@ -0,0 +1,24 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+Library("FuzzingImage")
+
+SOURCES += [
+ "TestDecoders.cpp",
+]
+
+FINAL_LIBRARY = "xul-gtest"
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+LOCAL_INCLUDES += [
+ "/dom/base",
+ "/gfx/2d",
+ "/image",
+ "/image/test/gtest",
+]
+
+LOCAL_INCLUDES += CONFIG["SKIA_INCLUDES"]
diff --git a/image/test/gtest/Common.cpp b/image/test/gtest/Common.cpp
new file mode 100644
index 0000000000..d0ddbecedf
--- /dev/null
+++ b/image/test/gtest/Common.cpp
@@ -0,0 +1,1076 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "Common.h"
+
+#include <cstdlib>
+
+#include "gfxPlatform.h"
+
+#include "ImageFactory.h"
+#include "imgITools.h"
+#include "mozilla/Preferences.h"
+#include "nsComponentManagerUtils.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsIFile.h"
+#include "nsIInputStream.h"
+#include "nsIProperties.h"
+#include "nsNetUtil.h"
+#include "mozilla/RefPtr.h"
+#include "nsStreamUtils.h"
+#include "nsString.h"
+
+namespace mozilla {
+namespace image {
+
+using namespace gfx;
+
+using std::vector;
+
+static bool sImageLibInitialized = false;
+
+AutoInitializeImageLib::AutoInitializeImageLib() {
+ if (MOZ_LIKELY(sImageLibInitialized)) {
+ return;
+ }
+
+ EXPECT_TRUE(NS_IsMainThread());
+ sImageLibInitialized = true;
+
+ // Ensure WebP is enabled to run decoder tests.
+ nsresult rv = Preferences::SetBool("image.webp.enabled", true);
+ EXPECT_TRUE(rv == NS_OK);
+
+ // Ensure AVIF is enabled to run decoder tests.
+ rv = Preferences::SetBool("image.avif.enabled", true);
+ EXPECT_TRUE(rv == NS_OK);
+ rv = Preferences::SetBool("image.avif.sequence.enabled", true);
+ EXPECT_TRUE(rv == NS_OK);
+
+#ifdef MOZ_JXL
+ // Ensure JXL is enabled to run decoder tests.
+ rv = Preferences::SetBool("image.jxl.enabled", true);
+ EXPECT_TRUE(rv == NS_OK);
+#endif
+
+ // Ensure that ImageLib services are initialized.
+ nsCOMPtr<imgITools> imgTools =
+ do_CreateInstance("@mozilla.org/image/tools;1");
+ EXPECT_TRUE(imgTools != nullptr);
+
+ // Ensure gfxPlatform is initialized.
+ gfxPlatform::GetPlatform();
+
+ // Ensure we always color manage images with gtests.
+ gfxPlatform::SetCMSModeOverride(CMSMode::All);
+
+ // Depending on initialization order, it is possible that our pref changes
+ // have not taken effect yet because there are pending gfx-related events on
+ // the main thread.
+ SpinPendingEvents();
+}
+
+void ImageBenchmarkBase::SetUp() {
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(mTestCase.mPath);
+ ASSERT_TRUE(inputStream != nullptr);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ nsresult rv = inputStream->Available(&length);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Write the data into a SourceBuffer.
+ mSourceBuffer = new SourceBuffer();
+ mSourceBuffer->ExpectLength(length);
+ rv = mSourceBuffer->AppendFromInputStream(inputStream, length);
+ ASSERT_NS_SUCCEEDED(rv);
+ mSourceBuffer->Complete(NS_OK);
+}
+
+void ImageBenchmarkBase::TearDown() {}
+
+///////////////////////////////////////////////////////////////////////////////
+// General Helpers
+///////////////////////////////////////////////////////////////////////////////
+
+// These macros work like gtest's ASSERT_* macros, except that they can be used
+// in functions that return values.
+#define ASSERT_TRUE_OR_RETURN(e, rv) \
+ EXPECT_TRUE(e); \
+ if (!(e)) { \
+ return rv; \
+ }
+
+#define ASSERT_EQ_OR_RETURN(a, b, rv) \
+ EXPECT_EQ(a, b); \
+ if ((a) != (b)) { \
+ return rv; \
+ }
+
+#define ASSERT_GE_OR_RETURN(a, b, rv) \
+ EXPECT_GE(a, b); \
+ if (!((a) >= (b))) { \
+ return rv; \
+ }
+
+#define ASSERT_LE_OR_RETURN(a, b, rv) \
+ EXPECT_LE(a, b); \
+ if (!((a) <= (b))) { \
+ return rv; \
+ }
+
+#define ASSERT_LT_OR_RETURN(a, b, rv) \
+ EXPECT_LT(a, b); \
+ if (!((a) < (b))) { \
+ return rv; \
+ }
+
+void SpinPendingEvents() {
+ nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
+ EXPECT_TRUE(mainThread != nullptr);
+
+ bool processed;
+ do {
+ processed = false;
+ nsresult rv = mainThread->ProcessNextEvent(false, &processed);
+ EXPECT_NS_SUCCEEDED(rv);
+ } while (processed);
+}
+
+already_AddRefed<nsIInputStream> LoadFile(const char* aRelativePath) {
+ nsresult rv;
+
+ nsCOMPtr<nsIProperties> dirService =
+ do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
+ ASSERT_TRUE_OR_RETURN(dirService != nullptr, nullptr);
+
+ // Retrieve the current working directory.
+ nsCOMPtr<nsIFile> file;
+ rv = dirService->Get(NS_OS_CURRENT_WORKING_DIR, NS_GET_IID(nsIFile),
+ getter_AddRefs(file));
+ ASSERT_TRUE_OR_RETURN(NS_SUCCEEDED(rv), nullptr);
+ // Construct the final path by appending the working path to the current
+ // working directory.
+ file->AppendNative(nsDependentCString(aRelativePath));
+
+ // Construct an input stream for the requested file.
+ nsCOMPtr<nsIInputStream> inputStream;
+ rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), file);
+ ASSERT_TRUE_OR_RETURN(NS_SUCCEEDED(rv), nullptr);
+
+ // Ensure the resulting input stream is buffered.
+ if (!NS_InputStreamIsBuffered(inputStream)) {
+ nsCOMPtr<nsIInputStream> bufStream;
+ rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream),
+ inputStream.forget(), 1024);
+ ASSERT_TRUE_OR_RETURN(NS_SUCCEEDED(rv), nullptr);
+ inputStream = bufStream;
+ }
+
+ return inputStream.forget();
+}
+
+bool IsSolidColor(SourceSurface* aSurface, BGRAColor aColor,
+ uint8_t aFuzz /* = 0 */) {
+ IntSize size = aSurface->GetSize();
+ return RectIsSolidColor(aSurface, IntRect(0, 0, size.width, size.height),
+ aColor, aFuzz);
+}
+
+bool RowsAreSolidColor(SourceSurface* aSurface, int32_t aStartRow,
+ int32_t aRowCount, BGRAColor aColor,
+ uint8_t aFuzz /* = 0 */) {
+ IntSize size = aSurface->GetSize();
+ return RectIsSolidColor(
+ aSurface, IntRect(0, aStartRow, size.width, aRowCount), aColor, aFuzz);
+}
+
+bool RectIsSolidColor(SourceSurface* aSurface, const IntRect& aRect,
+ BGRAColor aColor, uint8_t aFuzz /* = 0 */) {
+ IntSize surfaceSize = aSurface->GetSize();
+ IntRect rect =
+ aRect.Intersect(IntRect(0, 0, surfaceSize.width, surfaceSize.height));
+
+ RefPtr<DataSourceSurface> dataSurface = aSurface->GetDataSurface();
+ ASSERT_TRUE_OR_RETURN(dataSurface != nullptr, false);
+
+ DataSourceSurface::ScopedMap mapping(dataSurface,
+ DataSourceSurface::MapType::READ);
+ ASSERT_TRUE_OR_RETURN(mapping.IsMapped(), false);
+ ASSERT_EQ_OR_RETURN(mapping.GetStride(), surfaceSize.width * 4, false);
+
+ uint8_t* data = mapping.GetData();
+ ASSERT_TRUE_OR_RETURN(data != nullptr, false);
+
+ BGRAColor pmColor = aColor.Premultiply();
+ uint32_t expectedPixel = pmColor.AsPixel();
+
+ int32_t rowLength = mapping.GetStride();
+ for (int32_t row = rect.Y(); row < rect.YMost(); ++row) {
+ for (int32_t col = rect.X(); col < rect.XMost(); ++col) {
+ int32_t i = row * rowLength + col * 4;
+ uint32_t gotPixel = *reinterpret_cast<uint32_t*>(data + i);
+ if (expectedPixel != gotPixel) {
+ BGRAColor gotColor = BGRAColor::FromPixel(gotPixel);
+ if (abs(pmColor.mBlue - gotColor.mBlue) > aFuzz ||
+ abs(pmColor.mGreen - gotColor.mGreen) > aFuzz ||
+ abs(pmColor.mRed - gotColor.mRed) > aFuzz ||
+ abs(pmColor.mAlpha - gotColor.mAlpha) > aFuzz) {
+ EXPECT_EQ(expectedPixel, gotPixel)
+ << "Color mismatch for rectangle from " << aRect.TopLeft()
+ << " to " << aRect.BottomRight() << ": "
+ << "got rgba(" << static_cast<int>(gotColor.mRed) << ", "
+ << static_cast<int>(gotColor.mGreen) << ", "
+ << static_cast<int>(gotColor.mBlue) << ", "
+ << static_cast<int>(gotColor.mAlpha) << "), "
+ << "expected rgba(" << static_cast<int>(pmColor.mRed) << ", "
+ << static_cast<int>(pmColor.mGreen) << ", "
+ << static_cast<int>(pmColor.mBlue) << ", "
+ << static_cast<int>(pmColor.mAlpha) << ")";
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool RowHasPixels(SourceSurface* aSurface, int32_t aRow,
+ const vector<BGRAColor>& aPixels) {
+ ASSERT_GE_OR_RETURN(aRow, 0, false);
+
+ IntSize surfaceSize = aSurface->GetSize();
+ ASSERT_EQ_OR_RETURN(aPixels.size(), size_t(surfaceSize.width), false);
+ ASSERT_LT_OR_RETURN(aRow, surfaceSize.height, false);
+
+ RefPtr<DataSourceSurface> dataSurface = aSurface->GetDataSurface();
+ ASSERT_TRUE_OR_RETURN(dataSurface, false);
+
+ DataSourceSurface::ScopedMap mapping(dataSurface,
+ DataSourceSurface::MapType::READ);
+ ASSERT_TRUE_OR_RETURN(mapping.IsMapped(), false);
+ ASSERT_EQ_OR_RETURN(mapping.GetStride(), surfaceSize.width * 4, false);
+
+ uint8_t* data = mapping.GetData();
+ ASSERT_TRUE_OR_RETURN(data != nullptr, false);
+
+ int32_t rowLength = mapping.GetStride();
+ for (int32_t col = 0; col < surfaceSize.width; ++col) {
+ int32_t i = aRow * rowLength + col * 4;
+ uint32_t gotPixelData = *reinterpret_cast<uint32_t*>(data + i);
+ BGRAColor gotPixel = BGRAColor::FromPixel(gotPixelData);
+ EXPECT_EQ(aPixels[col].mBlue, gotPixel.mBlue);
+ EXPECT_EQ(aPixels[col].mGreen, gotPixel.mGreen);
+ EXPECT_EQ(aPixels[col].mRed, gotPixel.mRed);
+ EXPECT_EQ(aPixels[col].mAlpha, gotPixel.mAlpha);
+ ASSERT_EQ_OR_RETURN(aPixels[col].AsPixel(), gotPixelData, false);
+ }
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// SurfacePipe Helpers
+///////////////////////////////////////////////////////////////////////////////
+
+already_AddRefed<Decoder> CreateTrivialDecoder() {
+ DecoderType decoderType = DecoderFactory::GetDecoderType("image/gif");
+ auto sourceBuffer = MakeNotNull<RefPtr<SourceBuffer>>();
+ RefPtr<Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(
+ decoderType, sourceBuffer, Nothing(), DefaultDecoderFlags(),
+ DefaultSurfaceFlags());
+ return decoder.forget();
+}
+
+void AssertCorrectPipelineFinalState(SurfaceFilter* aFilter,
+ const IntRect& aInputSpaceRect,
+ const IntRect& aOutputSpaceRect) {
+ EXPECT_TRUE(aFilter->IsSurfaceFinished());
+ Maybe<SurfaceInvalidRect> invalidRect = aFilter->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isSome());
+ EXPECT_EQ(aInputSpaceRect, invalidRect->mInputSpaceRect.ToUnknownRect());
+ EXPECT_EQ(aOutputSpaceRect, invalidRect->mOutputSpaceRect.ToUnknownRect());
+}
+
+void CheckGeneratedImage(Decoder* aDecoder, const IntRect& aRect,
+ uint8_t aFuzz /* = 0 */) {
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ CheckGeneratedSurface(surface, aRect, BGRAColor::Green(),
+ BGRAColor::Transparent(), aFuzz);
+}
+
+void CheckGeneratedSurface(SourceSurface* aSurface, const IntRect& aRect,
+ const BGRAColor& aInnerColor,
+ const BGRAColor& aOuterColor,
+ uint8_t aFuzz /* = 0 */) {
+ const IntSize surfaceSize = aSurface->GetSize();
+
+ // This diagram shows how the surface is divided into regions that the code
+ // below tests for the correct content. The output rect is the bounds of the
+ // region labeled 'C'.
+ //
+ // +---------------------------+
+ // | A |
+ // +---------+--------+--------+
+ // | B | C | D |
+ // +---------+--------+--------+
+ // | E |
+ // +---------------------------+
+
+ // Check that the output rect itself is the inner color. (Region 'C'.)
+ EXPECT_TRUE(RectIsSolidColor(aSurface, aRect, aInnerColor, aFuzz));
+
+ // Check that the area above the output rect is the outer color. (Region 'A'.)
+ EXPECT_TRUE(RectIsSolidColor(aSurface,
+ IntRect(0, 0, surfaceSize.width, aRect.Y()),
+ aOuterColor, aFuzz));
+
+ // Check that the area to the left of the output rect is the outer color.
+ // (Region 'B'.)
+ EXPECT_TRUE(RectIsSolidColor(aSurface,
+ IntRect(0, aRect.Y(), aRect.X(), aRect.YMost()),
+ aOuterColor, aFuzz));
+
+ // Check that the area to the right of the output rect is the outer color.
+ // (Region 'D'.)
+ const int32_t widthOnRight = surfaceSize.width - aRect.XMost();
+ EXPECT_TRUE(RectIsSolidColor(
+ aSurface, IntRect(aRect.XMost(), aRect.Y(), widthOnRight, aRect.YMost()),
+ aOuterColor, aFuzz));
+
+ // Check that the area below the output rect is the outer color. (Region 'E'.)
+ const int32_t heightBelow = surfaceSize.height - aRect.YMost();
+ EXPECT_TRUE(RectIsSolidColor(
+ aSurface, IntRect(0, aRect.YMost(), surfaceSize.width, heightBelow),
+ aOuterColor, aFuzz));
+}
+
+void CheckWritePixels(Decoder* aDecoder, SurfaceFilter* aFilter,
+ const Maybe<IntRect>& aOutputRect /* = Nothing() */,
+ const Maybe<IntRect>& aInputRect /* = Nothing() */,
+ const Maybe<IntRect>& aInputWriteRect /* = Nothing() */,
+ const Maybe<IntRect>& aOutputWriteRect /* = Nothing() */,
+ uint8_t aFuzz /* = 0 */) {
+ CheckTransformedWritePixels(aDecoder, aFilter, BGRAColor::Green(),
+ BGRAColor::Green(), aOutputRect, aInputRect,
+ aInputWriteRect, aOutputWriteRect, aFuzz);
+}
+
+void CheckTransformedWritePixels(
+ Decoder* aDecoder, SurfaceFilter* aFilter, const BGRAColor& aInputColor,
+ const BGRAColor& aOutputColor,
+ const Maybe<IntRect>& aOutputRect /* = Nothing() */,
+ const Maybe<IntRect>& aInputRect /* = Nothing() */,
+ const Maybe<IntRect>& aInputWriteRect /* = Nothing() */,
+ const Maybe<IntRect>& aOutputWriteRect /* = Nothing() */,
+ uint8_t aFuzz /* = 0 */) {
+ IntRect outputRect = aOutputRect.valueOr(IntRect(0, 0, 100, 100));
+ IntRect inputRect = aInputRect.valueOr(IntRect(0, 0, 100, 100));
+ IntRect inputWriteRect = aInputWriteRect.valueOr(inputRect);
+ IntRect outputWriteRect = aOutputWriteRect.valueOr(outputRect);
+
+ // Fill the image.
+ int32_t count = 0;
+ auto result = aFilter->WritePixels<uint32_t>([&] {
+ ++count;
+ return AsVariant(aInputColor.AsPixel());
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(inputWriteRect.Width() * inputWriteRect.Height(), count);
+
+ AssertCorrectPipelineFinalState(aFilter, inputRect, outputRect);
+
+ // Attempt to write more data and make sure nothing changes.
+ const int32_t oldCount = count;
+ result = aFilter->WritePixels<uint32_t>([&] {
+ ++count;
+ return AsVariant(aInputColor.AsPixel());
+ });
+ EXPECT_EQ(oldCount, count);
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_TRUE(aFilter->IsSurfaceFinished());
+ Maybe<SurfaceInvalidRect> invalidRect = aFilter->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isNothing());
+
+ // Attempt to advance to the next row and make sure nothing changes.
+ aFilter->AdvanceRow();
+ EXPECT_TRUE(aFilter->IsSurfaceFinished());
+ invalidRect = aFilter->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isNothing());
+
+ // Check that the generated image is correct.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ CheckGeneratedSurface(surface, outputWriteRect, aOutputColor,
+ BGRAColor::Transparent(), aFuzz);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Test Data
+///////////////////////////////////////////////////////////////////////////////
+
+ImageTestCase GreenPNGTestCase() {
+ return ImageTestCase("green.png", "image/png", IntSize(100, 100));
+}
+
+ImageTestCase GreenGIFTestCase() {
+ return ImageTestCase("green.gif", "image/gif", IntSize(100, 100));
+}
+
+ImageTestCase GreenJPGTestCase() {
+ return ImageTestCase("green.jpg", "image/jpeg", IntSize(100, 100),
+ TEST_CASE_IS_FUZZY);
+}
+
+ImageTestCase GreenBMPTestCase() {
+ return ImageTestCase("green.bmp", "image/bmp", IntSize(100, 100));
+}
+
+ImageTestCase GreenICOTestCase() {
+ // This ICO contains a 32-bit BMP, and we use a BMP's alpha data by default
+ // when the BMP is embedded in an ICO, so it's transparent.
+ return ImageTestCase("green.ico", "image/x-icon", IntSize(100, 100),
+ TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase GreenIconTestCase() {
+ return ImageTestCase("green.icon", "image/icon", IntSize(100, 100),
+ TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase GreenWebPTestCase() {
+ return ImageTestCase("green.webp", "image/webp", IntSize(100, 100));
+}
+
+ImageTestCase GreenAVIFTestCase() {
+ return ImageTestCase("green.avif", "image/avif", IntSize(100, 100));
+}
+
+ImageTestCase NonzeroReservedAVIFTestCase() {
+ auto testCase = ImageTestCase("hdlr-nonzero-reserved-bug-1727033.avif",
+ "image/avif", IntSize(1, 1));
+ testCase.mColor = BGRAColor(0x00, 0x00, 0x00, 0xFF);
+ return testCase;
+}
+
+ImageTestCase MultipleColrAVIFTestCase() {
+ auto testCase = ImageTestCase("valid-avif-colr-nclx-and-prof.avif",
+ "image/avif", IntSize(1, 1));
+ testCase.mColor = BGRAColor(0x00, 0x00, 0x00, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Transparent10bit420AVIFTestCase() {
+ auto testCase =
+ ImageTestCase("transparent-green-50pct-10bit-yuv420.avif", "image/avif",
+ IntSize(100, 100), TEST_CASE_IS_TRANSPARENT);
+ testCase.mColor = BGRAColor(0x00, 0xFF, 0x00, 0x80);
+ return testCase;
+}
+
+ImageTestCase Transparent10bit422AVIFTestCase() {
+ auto testCase =
+ ImageTestCase("transparent-green-50pct-10bit-yuv422.avif", "image/avif",
+ IntSize(100, 100), TEST_CASE_IS_TRANSPARENT);
+ testCase.mColor = BGRAColor(0x00, 0xFF, 0x00, 0x80);
+ return testCase;
+}
+
+ImageTestCase Transparent10bit444AVIFTestCase() {
+ auto testCase =
+ ImageTestCase("transparent-green-50pct-10bit-yuv444.avif", "image/avif",
+ IntSize(100, 100), TEST_CASE_IS_TRANSPARENT);
+ testCase.mColor = BGRAColor(0x00, 0xFF, 0x00, 0x80);
+ return testCase;
+}
+
+ImageTestCase Transparent12bit420AVIFTestCase() {
+ auto testCase =
+ ImageTestCase("transparent-green-50pct-12bit-yuv420.avif", "image/avif",
+ IntSize(100, 100), TEST_CASE_IS_TRANSPARENT);
+ testCase.mColor = BGRAColor(0x00, 0xFF, 0x00, 0x80);
+ return testCase;
+}
+
+ImageTestCase Transparent12bit422AVIFTestCase() {
+ auto testCase =
+ ImageTestCase("transparent-green-50pct-12bit-yuv422.avif", "image/avif",
+ IntSize(100, 100), TEST_CASE_IS_TRANSPARENT);
+ testCase.mColor = BGRAColor(0x00, 0xFF, 0x00, 0x80);
+ return testCase;
+}
+
+ImageTestCase Transparent12bit444AVIFTestCase() {
+ auto testCase =
+ ImageTestCase("transparent-green-50pct-12bit-yuv444.avif", "image/avif",
+ IntSize(100, 100), TEST_CASE_IS_TRANSPARENT);
+ testCase.mColor = BGRAColor(0x00, 0xFF, 0x00, 0x80);
+ return testCase;
+}
+
+ImageTestCase Transparent8bit420AVIFTestCase() {
+ auto testCase =
+ ImageTestCase("transparent-green-50pct-8bit-yuv420.avif", "image/avif",
+ IntSize(100, 100), TEST_CASE_IS_TRANSPARENT);
+ // Small error is expected
+ testCase.mColor = BGRAColor(0x02, 0xFF, 0x00, 0x80);
+ return testCase;
+}
+
+ImageTestCase Transparent8bit422AVIFTestCase() {
+ auto testCase =
+ ImageTestCase("transparent-green-50pct-8bit-yuv422.avif", "image/avif",
+ IntSize(100, 100), TEST_CASE_IS_TRANSPARENT);
+ // Small error is expected
+ testCase.mColor = BGRAColor(0x02, 0xFF, 0x00, 0x80);
+ return testCase;
+}
+
+ImageTestCase Transparent8bit444AVIFTestCase() {
+ auto testCase =
+ ImageTestCase("transparent-green-50pct-8bit-yuv444.avif", "image/avif",
+ IntSize(100, 100), TEST_CASE_IS_TRANSPARENT);
+ // Small error is expected
+ testCase.mColor = BGRAColor(0x02, 0xFF, 0x00, 0x80);
+ return testCase;
+}
+
+ImageTestCase Gray8bitLimitedRangeBT601AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-8bit-limited-range-bt601.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray8bitLimitedRangeBT709AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-8bit-limited-range-bt709.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray8bitLimitedRangeBT2020AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-8bit-limited-range-bt2020.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray8bitFullRangeBT601AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-8bit-full-range-bt601.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray8bitFullRangeBT709AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-8bit-full-range-bt709.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray8bitFullRangeBT2020AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-8bit-full-range-bt2020.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray10bitLimitedRangeBT601AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-10bit-limited-range-bt601.avif",
+ "image/avif", IntSize(100, 100));
+ // Small error is expected
+ testCase.mColor = BGRAColor(0xEA, 0xEA, 0xEA, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray10bitLimitedRangeBT709AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-10bit-limited-range-bt709.avif",
+ "image/avif", IntSize(100, 100));
+ // Small error is expected
+ testCase.mColor = BGRAColor(0xEA, 0xEA, 0xEA, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray10bitLimitedRangeBT2020AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-10bit-limited-range-bt2020.avif",
+ "image/avif", IntSize(100, 100));
+ // Small error is expected
+ testCase.mColor = BGRAColor(0xEA, 0xEA, 0xEA, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray10bitFullRangeBT601AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-10bit-full-range-bt601.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray10bitFullRangeBT709AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-10bit-full-range-bt709.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray10bitFullRangeBT2020AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-10bit-full-range-bt2020.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray12bitLimitedRangeBT601AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-12bit-limited-range-bt601.avif",
+ "image/avif", IntSize(100, 100));
+ // Small error is expected
+ testCase.mColor = BGRAColor(0xEA, 0xEA, 0xEA, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray12bitLimitedRangeBT709AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-12bit-limited-range-bt709.avif",
+ "image/avif", IntSize(100, 100));
+ // Small error is expected
+ testCase.mColor = BGRAColor(0xEA, 0xEA, 0xEA, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray12bitLimitedRangeBT2020AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-12bit-limited-range-bt2020.avif",
+ "image/avif", IntSize(100, 100));
+ // Small error is expected
+ testCase.mColor = BGRAColor(0xEA, 0xEA, 0xEA, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray12bitFullRangeBT601AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-12bit-full-range-bt601.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray12bitFullRangeBT709AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-12bit-full-range-bt709.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray12bitFullRangeBT2020AVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-12bit-full-range-bt2020.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray8bitLimitedRangeGrayscaleAVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-8bit-limited-range-grayscale.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray8bitFullRangeGrayscaleAVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-8bit-full-range-grayscale.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray10bitLimitedRangeGrayscaleAVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-10bit-limited-range-grayscale.avif",
+ "image/avif", IntSize(100, 100));
+ // Small error is expected
+ testCase.mColor = BGRAColor(0xEA, 0xEA, 0xEA, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray10bitFullRangeGrayscaleAVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-10bit-full-range-grayscale.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray12bitLimitedRangeGrayscaleAVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-12bit-limited-range-grayscale.avif",
+ "image/avif", IntSize(100, 100));
+ // Small error is expected
+ testCase.mColor = BGRAColor(0xEA, 0xEA, 0xEA, 0xFF);
+ return testCase;
+}
+
+ImageTestCase Gray12bitFullRangeGrayscaleAVIFTestCase() {
+ auto testCase = ImageTestCase("gray-235-12bit-full-range-grayscale.avif",
+ "image/avif", IntSize(100, 100));
+ testCase.mColor = BGRAColor(0xEB, 0xEB, 0xEB, 0xFF);
+ return testCase;
+}
+
+ImageTestCase StackCheckAVIFTestCase() {
+ return ImageTestCase("stackcheck.avif", "image/avif", IntSize(4096, 2924),
+ TEST_CASE_IGNORE_OUTPUT);
+}
+
+// Add TEST_CASE_IGNORE_OUTPUT since this isn't a solid green image and we just
+// want to test that it decodes correctly.
+ImageTestCase MultiLayerAVIFTestCase() {
+ return ImageTestCase("multilayer.avif", "image/avif", IntSize(1280, 720),
+ TEST_CASE_IGNORE_OUTPUT);
+}
+
+ImageTestCase LargeWebPTestCase() {
+ return ImageTestCase("large.webp", "image/webp", IntSize(1200, 660),
+ TEST_CASE_IGNORE_OUTPUT);
+}
+
+ImageTestCase LargeAVIFTestCase() {
+ return ImageTestCase("large.avif", "image/avif", IntSize(1200, 660),
+ TEST_CASE_IGNORE_OUTPUT);
+}
+
+ImageTestCase GreenWebPIccSrgbTestCase() {
+ return ImageTestCase("green.icc_srgb.webp", "image/webp", IntSize(100, 100));
+}
+
+ImageTestCase GreenFirstFrameAnimatedGIFTestCase() {
+ return ImageTestCase("first-frame-green.gif", "image/gif", IntSize(100, 100),
+ TEST_CASE_IS_ANIMATED);
+}
+
+ImageTestCase GreenFirstFrameAnimatedPNGTestCase() {
+ return ImageTestCase("first-frame-green.png", "image/png", IntSize(100, 100),
+ TEST_CASE_IS_TRANSPARENT | TEST_CASE_IS_ANIMATED);
+}
+
+ImageTestCase GreenFirstFrameAnimatedWebPTestCase() {
+ return ImageTestCase("first-frame-green.webp", "image/webp",
+ IntSize(100, 100), TEST_CASE_IS_ANIMATED);
+}
+
+ImageTestCase GreenFirstFrameAnimatedAVIFTestCase() {
+ return ImageTestCase("first-frame-green.avif", "image/avif",
+ IntSize(100, 100), TEST_CASE_IS_ANIMATED);
+}
+
+ImageTestCase BlendAnimatedGIFTestCase() {
+ return ImageTestCase("blend.gif", "image/gif", IntSize(100, 100),
+ TEST_CASE_IS_ANIMATED);
+}
+
+ImageTestCase BlendAnimatedPNGTestCase() {
+ return ImageTestCase("blend.png", "image/png", IntSize(100, 100),
+ TEST_CASE_IS_TRANSPARENT | TEST_CASE_IS_ANIMATED);
+}
+
+ImageTestCase BlendAnimatedWebPTestCase() {
+ return ImageTestCase("blend.webp", "image/webp", IntSize(100, 100),
+ TEST_CASE_IS_TRANSPARENT | TEST_CASE_IS_ANIMATED);
+}
+
+ImageTestCase BlendAnimatedAVIFTestCase() {
+ return ImageTestCase("blend.avif", "image/avif", IntSize(100, 100),
+ TEST_CASE_IS_TRANSPARENT | TEST_CASE_IS_ANIMATED);
+}
+
+ImageTestCase CorruptTestCase() {
+ return ImageTestCase("corrupt.jpg", "image/jpeg", IntSize(100, 100),
+ TEST_CASE_HAS_ERROR);
+}
+
+ImageTestCase CorruptBMPWithTruncatedHeader() {
+ // This BMP has a header which is truncated right between the BIH and the
+ // bitfields, which is a particularly error-prone place w.r.t. the BMP decoder
+ // state machine.
+ return ImageTestCase("invalid-truncated-metadata.bmp", "image/bmp",
+ IntSize(100, 100), TEST_CASE_HAS_ERROR);
+}
+
+ImageTestCase CorruptICOWithBadBMPWidthTestCase() {
+ // This ICO contains a BMP icon which has a width that doesn't match the size
+ // listed in the corresponding ICO directory entry.
+ return ImageTestCase("corrupt-with-bad-bmp-width.ico", "image/x-icon",
+ IntSize(100, 100), TEST_CASE_HAS_ERROR);
+}
+
+ImageTestCase CorruptICOWithBadBMPHeightTestCase() {
+ // This ICO contains a BMP icon which has a height that doesn't match the size
+ // listed in the corresponding ICO directory entry.
+ return ImageTestCase("corrupt-with-bad-bmp-height.ico", "image/x-icon",
+ IntSize(100, 100), TEST_CASE_HAS_ERROR);
+}
+
+ImageTestCase CorruptICOWithBadBppTestCase() {
+ // This test case is an ICO with a BPP (15) in the ICO header which differs
+ // from that in the BMP header itself (1). It should ignore the ICO BPP when
+ // the BMP BPP is available and thus correctly decode the image.
+ return ImageTestCase("corrupt-with-bad-ico-bpp.ico", "image/x-icon",
+ IntSize(100, 100), TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase CorruptAVIFTestCase() {
+ return ImageTestCase("bug-1655846.avif", "image/avif", IntSize(100, 100),
+ TEST_CASE_HAS_ERROR);
+}
+
+ImageTestCase TransparentAVIFTestCase() {
+ return ImageTestCase("transparent.avif", "image/avif", IntSize(1200, 1200),
+ TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase TransparentPNGTestCase() {
+ return ImageTestCase("transparent.png", "image/png", IntSize(32, 32),
+ TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase TransparentGIFTestCase() {
+ return ImageTestCase("transparent.gif", "image/gif", IntSize(16, 16),
+ TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase TransparentWebPTestCase() {
+ ImageTestCase test("transparent.webp", "image/webp", IntSize(100, 100),
+ TEST_CASE_IS_TRANSPARENT);
+ test.mColor = BGRAColor::Transparent();
+ return test;
+}
+
+ImageTestCase TransparentNoAlphaHeaderWebPTestCase() {
+ ImageTestCase test("transparent-no-alpha-header.webp", "image/webp",
+ IntSize(100, 100), TEST_CASE_IS_FUZZY);
+ test.mColor = BGRAColor(0x00, 0x00, 0x00, 0xFF); // black
+ return test;
+}
+
+ImageTestCase FirstFramePaddingGIFTestCase() {
+ return ImageTestCase("transparent.gif", "image/gif", IntSize(16, 16),
+ TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase TransparentIfWithinICOBMPTestCase(TestCaseFlags aFlags) {
+ // This is a BMP that is only transparent when decoded as if it is within an
+ // ICO file. (Note: aFlags needs to be set to TEST_CASE_DEFAULT_FLAGS or
+ // TEST_CASE_IS_TRANSPARENT accordingly.)
+ return ImageTestCase("transparent-if-within-ico.bmp", "image/bmp",
+ IntSize(32, 32), aFlags);
+}
+
+ImageTestCase RLE4BMPTestCase() {
+ return ImageTestCase("rle4.bmp", "image/bmp", IntSize(320, 240),
+ TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase RLE8BMPTestCase() {
+ return ImageTestCase("rle8.bmp", "image/bmp", IntSize(32, 32),
+ TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase NoFrameDelayGIFTestCase() {
+ // This is an invalid (or at least, questionably valid) GIF that's animated
+ // even though it specifies a frame delay of zero. It's animated, but it's not
+ // marked TEST_CASE_IS_ANIMATED because the metadata decoder can't detect that
+ // it's animated.
+ return ImageTestCase("no-frame-delay.gif", "image/gif", IntSize(100, 100));
+}
+
+ImageTestCase ExtraImageSubBlocksAnimatedGIFTestCase() {
+ // This is a corrupt GIF that has extra image sub blocks between the first and
+ // second frame.
+ return ImageTestCase("animated-with-extra-image-sub-blocks.gif", "image/gif",
+ IntSize(100, 100));
+}
+
+ImageTestCase DownscaledPNGTestCase() {
+ // This testcase (and all the other "downscaled") testcases) consists of 25
+ // lines of green, followed by 25 lines of red, followed by 25 lines of green,
+ // followed by 25 more lines of red. It's intended that tests downscale it
+ // from 100x100 to 20x20, so we specify a 20x20 output size.
+ return ImageTestCase("downscaled.png", "image/png", IntSize(100, 100),
+ IntSize(20, 20));
+}
+
+ImageTestCase DownscaledGIFTestCase() {
+ return ImageTestCase("downscaled.gif", "image/gif", IntSize(100, 100),
+ IntSize(20, 20));
+}
+
+ImageTestCase DownscaledJPGTestCase() {
+ return ImageTestCase("downscaled.jpg", "image/jpeg", IntSize(100, 100),
+ IntSize(20, 20));
+}
+
+ImageTestCase DownscaledBMPTestCase() {
+ return ImageTestCase("downscaled.bmp", "image/bmp", IntSize(100, 100),
+ IntSize(20, 20));
+}
+
+ImageTestCase DownscaledICOTestCase() {
+ return ImageTestCase("downscaled.ico", "image/x-icon", IntSize(100, 100),
+ IntSize(20, 20), TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase DownscaledIconTestCase() {
+ return ImageTestCase("downscaled.icon", "image/icon", IntSize(100, 100),
+ IntSize(20, 20), TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase DownscaledWebPTestCase() {
+ return ImageTestCase("downscaled.webp", "image/webp", IntSize(100, 100),
+ IntSize(20, 20));
+}
+
+ImageTestCase DownscaledAVIFTestCase() {
+ return ImageTestCase("downscaled.avif", "image/avif", IntSize(100, 100),
+ IntSize(20, 20));
+}
+
+ImageTestCase DownscaledTransparentICOWithANDMaskTestCase() {
+ // This test case is an ICO with AND mask transparency. We want to ensure that
+ // we can downscale it without crashing or triggering ASAN failures, but its
+ // content isn't simple to verify, so for now we don't check the output.
+ return ImageTestCase("transparent-ico-with-and-mask.ico", "image/x-icon",
+ IntSize(32, 32), IntSize(20, 20),
+ TEST_CASE_IS_TRANSPARENT | TEST_CASE_IGNORE_OUTPUT);
+}
+
+ImageTestCase TruncatedSmallGIFTestCase() {
+ return ImageTestCase("green-1x1-truncated.gif", "image/gif", IntSize(1, 1),
+ TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase LargeICOWithBMPTestCase() {
+ return ImageTestCase("green-large-bmp.ico", "image/x-icon", IntSize(256, 256),
+ TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase LargeICOWithPNGTestCase() {
+ return ImageTestCase("green-large-png.ico", "image/x-icon", IntSize(512, 512),
+ TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase GreenMultipleSizesICOTestCase() {
+ return ImageTestCase("green-multiple-sizes.ico", "image/x-icon",
+ IntSize(256, 256));
+}
+
+ImageTestCase PerfGrayJPGTestCase() {
+ return ImageTestCase("perf_gray.jpg", "image/jpeg", IntSize(1000, 1000));
+}
+
+ImageTestCase PerfCmykJPGTestCase() {
+ return ImageTestCase("perf_cmyk.jpg", "image/jpeg", IntSize(1000, 1000));
+}
+
+ImageTestCase PerfYCbCrJPGTestCase() {
+ return ImageTestCase("perf_ycbcr.jpg", "image/jpeg", IntSize(1000, 1000));
+}
+
+ImageTestCase PerfRgbPNGTestCase() {
+ return ImageTestCase("perf_srgb.png", "image/png", IntSize(1000, 1000));
+}
+
+ImageTestCase PerfRgbAlphaPNGTestCase() {
+ return ImageTestCase("perf_srgb_alpha.png", "image/png", IntSize(1000, 1000),
+ TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase PerfGrayPNGTestCase() {
+ return ImageTestCase("perf_gray.png", "image/png", IntSize(1000, 1000));
+}
+
+ImageTestCase PerfGrayAlphaPNGTestCase() {
+ return ImageTestCase("perf_gray_alpha.png", "image/png", IntSize(1000, 1000),
+ TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase PerfRgbLosslessWebPTestCase() {
+ return ImageTestCase("perf_srgb_lossless.webp", "image/webp",
+ IntSize(1000, 1000));
+}
+
+ImageTestCase PerfRgbAlphaLosslessWebPTestCase() {
+ return ImageTestCase("perf_srgb_alpha_lossless.webp", "image/webp",
+ IntSize(1000, 1000), TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase PerfRgbLossyWebPTestCase() {
+ return ImageTestCase("perf_srgb_lossy.webp", "image/webp",
+ IntSize(1000, 1000));
+}
+
+ImageTestCase PerfRgbAlphaLossyWebPTestCase() {
+ return ImageTestCase("perf_srgb_alpha_lossy.webp", "image/webp",
+ IntSize(1000, 1000), TEST_CASE_IS_TRANSPARENT);
+}
+
+ImageTestCase PerfRgbGIFTestCase() {
+ return ImageTestCase("perf_srgb.gif", "image/gif", IntSize(1000, 1000));
+}
+
+#ifdef MOZ_JXL
+ImageTestCase GreenJXLTestCase() {
+ return ImageTestCase("green.jxl", "image/jxl", IntSize(100, 100));
+}
+
+ImageTestCase DownscaledJXLTestCase() {
+ return ImageTestCase("downscaled.jxl", "image/jxl", IntSize(100, 100),
+ IntSize(20, 20));
+}
+
+ImageTestCase LargeJXLTestCase() {
+ return ImageTestCase("large.jxl", "image/jxl", IntSize(1200, 660),
+ TEST_CASE_IGNORE_OUTPUT);
+}
+
+ImageTestCase TransparentJXLTestCase() {
+ return ImageTestCase("transparent.jxl", "image/jxl", IntSize(1200, 1200),
+ TEST_CASE_IS_TRANSPARENT);
+}
+#endif
+
+ImageTestCase ExifResolutionTestCase() {
+ return ImageTestCase("exif_resolution.jpg", "image/jpeg", IntSize(100, 50));
+}
+
+RefPtr<Image> TestCaseToDecodedImage(const ImageTestCase& aTestCase) {
+ RefPtr<Image> image = ImageFactory::CreateAnonymousImage(
+ nsDependentCString(aTestCase.mMimeType));
+ MOZ_RELEASE_ASSERT(!image->HasError());
+
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
+ MOZ_RELEASE_ASSERT(inputStream);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ nsresult rv = inputStream->Available(&length);
+ MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
+
+ // Write the data into the image.
+ rv = image->OnImageDataAvailable(nullptr, inputStream, 0,
+ static_cast<uint32_t>(length));
+ MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
+
+ // Let the image know we've sent all the data.
+ rv = image->OnImageDataComplete(nullptr, NS_OK, true);
+ MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
+
+ RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
+ tracker->SyncNotifyProgress(FLAG_LOAD_COMPLETE);
+
+ // Use GetFrame() to force a sync decode of the image.
+ RefPtr<SourceSurface> surface = image->GetFrame(
+ imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE);
+ Unused << surface;
+ return image;
+}
+
+} // namespace image
+} // namespace mozilla
diff --git a/image/test/gtest/Common.h b/image/test/gtest/Common.h
new file mode 100644
index 0000000000..bd6ae64a42
--- /dev/null
+++ b/image/test/gtest/Common.h
@@ -0,0 +1,600 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_image_test_gtest_Common_h
+#define mozilla_image_test_gtest_Common_h
+
+#include <vector>
+
+#include "gtest/gtest.h"
+
+#include "mozilla/Attributes.h"
+#include "mozilla/gtest/MozAssertions.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/gfx/2D.h"
+#include "Decoder.h"
+#include "gfxColor.h"
+#include "gfxPlatform.h"
+#include "nsCOMPtr.h"
+#include "SurfaceFlags.h"
+#include "SurfacePipe.h"
+#include "SurfacePipeFactory.h"
+
+class nsIInputStream;
+
+namespace mozilla {
+namespace image {
+
+///////////////////////////////////////////////////////////////////////////////
+// Types
+///////////////////////////////////////////////////////////////////////////////
+
+struct BGRAColor {
+ BGRAColor() : BGRAColor(0, 0, 0, 0) {}
+
+ BGRAColor(uint8_t aBlue, uint8_t aGreen, uint8_t aRed, uint8_t aAlpha,
+ bool aPremultiplied = false, bool asRGB = true)
+ : mBlue(aBlue),
+ mGreen(aGreen),
+ mRed(aRed),
+ mAlpha(aAlpha),
+ mPremultiplied(aPremultiplied),
+ msRGB(asRGB) {}
+
+ static BGRAColor Green() { return BGRAColor(0x00, 0xFF, 0x00, 0xFF); }
+ static BGRAColor Red() { return BGRAColor(0x00, 0x00, 0xFF, 0xFF); }
+ static BGRAColor Blue() { return BGRAColor(0xFF, 0x00, 0x00, 0xFF); }
+ static BGRAColor Transparent() { return BGRAColor(0x00, 0x00, 0x00, 0x00); }
+
+ static BGRAColor FromPixel(uint32_t aPixel) {
+ uint8_t r, g, b, a;
+ r = (aPixel >> gfx::SurfaceFormatBit::OS_R) & 0xFF;
+ g = (aPixel >> gfx::SurfaceFormatBit::OS_G) & 0xFF;
+ b = (aPixel >> gfx::SurfaceFormatBit::OS_B) & 0xFF;
+ a = (aPixel >> gfx::SurfaceFormatBit::OS_A) & 0xFF;
+ return BGRAColor(b, g, r, a, true);
+ }
+
+ BGRAColor DeviceColor() const {
+ MOZ_ASSERT(!mPremultiplied);
+ if (msRGB) {
+ gfx::DeviceColor color = gfx::ToDeviceColor(
+ gfx::sRGBColor(float(mRed) / 255.0f, float(mGreen) / 255.0f,
+ float(mBlue) / 255.0f, 1.0));
+ return BGRAColor(uint8_t(color.b * 255.0f), uint8_t(color.g * 255.0f),
+ uint8_t(color.r * 255.0f), mAlpha, mPremultiplied,
+ /* asRGB */ false);
+ }
+ return *this;
+ }
+
+ BGRAColor sRGBColor() const {
+ MOZ_ASSERT(msRGB);
+ MOZ_ASSERT(!mPremultiplied);
+ return *this;
+ }
+
+ BGRAColor Premultiply() const {
+ if (!mPremultiplied) {
+ return BGRAColor(gfxPreMultiply(mBlue, mAlpha),
+ gfxPreMultiply(mGreen, mAlpha),
+ gfxPreMultiply(mRed, mAlpha), mAlpha, true);
+ }
+ return *this;
+ }
+
+ uint32_t AsPixel() const {
+ if (!mPremultiplied) {
+ return gfxPackedPixel(mAlpha, mRed, mGreen, mBlue);
+ }
+ return gfxPackedPixelNoPreMultiply(mAlpha, mRed, mGreen, mBlue);
+ }
+
+ uint8_t mBlue;
+ uint8_t mGreen;
+ uint8_t mRed;
+ uint8_t mAlpha;
+ bool mPremultiplied;
+ bool msRGB;
+};
+
+enum TestCaseFlags {
+ TEST_CASE_DEFAULT_FLAGS = 0,
+ TEST_CASE_IS_FUZZY = 1 << 0,
+ TEST_CASE_HAS_ERROR = 1 << 1,
+ TEST_CASE_IS_TRANSPARENT = 1 << 2,
+ TEST_CASE_IS_ANIMATED = 1 << 3,
+ TEST_CASE_IGNORE_OUTPUT = 1 << 4,
+ TEST_CASE_ASSUME_SRGB_OUTPUT = 1 << 5,
+};
+
+struct ImageTestCase {
+ ImageTestCase(const char* aPath, const char* aMimeType, gfx::IntSize aSize,
+ uint32_t aFlags = TEST_CASE_DEFAULT_FLAGS)
+ : mPath(aPath),
+ mMimeType(aMimeType),
+ mSize(aSize),
+ mOutputSize(aSize),
+ mFlags(aFlags),
+ mSurfaceFlags(DefaultSurfaceFlags()),
+ mColor(BGRAColor::Green()) {}
+
+ ImageTestCase(const char* aPath, const char* aMimeType, gfx::IntSize aSize,
+ gfx::IntSize aOutputSize,
+ uint32_t aFlags = TEST_CASE_DEFAULT_FLAGS)
+ : mPath(aPath),
+ mMimeType(aMimeType),
+ mSize(aSize),
+ mOutputSize(aOutputSize),
+ mFlags(aFlags),
+ mSurfaceFlags(DefaultSurfaceFlags()),
+ mColor(BGRAColor::Green()) {}
+
+ ImageTestCase WithSurfaceFlags(SurfaceFlags aSurfaceFlags) const {
+ ImageTestCase self = *this;
+ self.mSurfaceFlags = aSurfaceFlags;
+ return self;
+ }
+
+ ImageTestCase WithFlags(uint32_t aFlags) const {
+ ImageTestCase self = *this;
+ self.mFlags = aFlags;
+ return self;
+ }
+
+ BGRAColor ChooseColor(const BGRAColor& aColor) const {
+ // If we are forcing the output to be sRGB via the surface flag, or the
+ // test case is marked as assuming sRGB (used when the image itself is not
+ // explicitly tagged, and as a result, imagelib won't perform any color
+ // conversion), we should use the sRGB presentation of the color.
+ if ((mSurfaceFlags & SurfaceFlags::TO_SRGB_COLORSPACE) ||
+ (mFlags & TEST_CASE_ASSUME_SRGB_OUTPUT)) {
+ return aColor.sRGBColor();
+ }
+ return aColor.DeviceColor();
+ }
+
+ BGRAColor Color() const { return ChooseColor(mColor); }
+
+ uint8_t Fuzz() const {
+ // If we are using device space, there can easily be off by 1 channel errors
+ // depending on the color profile and how the rounding went.
+ if (mFlags & TEST_CASE_IS_FUZZY ||
+ !(mSurfaceFlags & SurfaceFlags::TO_SRGB_COLORSPACE)) {
+ return 1;
+ }
+ return 0;
+ }
+
+ const char* mPath;
+ const char* mMimeType;
+ gfx::IntSize mSize;
+ gfx::IntSize mOutputSize;
+ uint32_t mFlags;
+ SurfaceFlags mSurfaceFlags;
+ BGRAColor mColor;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// General Helpers
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * A RAII class that ensure that ImageLib services are available. Any tests that
+ * require ImageLib to be initialized (for example, any test that uses the
+ * SurfaceCache; see image::EnsureModuleInitialized() for the full list) can
+ * use this class to ensure that ImageLib services are available. Failure to do
+ * so can result in strange, non-deterministic failures.
+ */
+class AutoInitializeImageLib {
+ public:
+ AutoInitializeImageLib();
+};
+
+/**
+ * A test fixture class used for benchmark tests. It preloads the image data
+ * from disk to avoid including that in the timing.
+ */
+class ImageBenchmarkBase : public ::testing::Test {
+ protected:
+ ImageBenchmarkBase(const ImageTestCase& aTestCase) : mTestCase(aTestCase) {}
+
+ void SetUp() override;
+ void TearDown() override;
+
+ AutoInitializeImageLib mInit;
+ ImageTestCase mTestCase;
+ RefPtr<SourceBuffer> mSourceBuffer;
+};
+
+/// Spins on the main thread to process any pending events.
+void SpinPendingEvents();
+
+/// Loads a file from the current directory. @return an nsIInputStream for it.
+already_AddRefed<nsIInputStream> LoadFile(const char* aRelativePath);
+
+/**
+ * @returns true if every pixel of @aSurface is @aColor.
+ *
+ * If @aFuzz is nonzero, a tolerance of @aFuzz is allowed in each color
+ * component. This may be necessary for tests that involve JPEG images or
+ * downscaling.
+ */
+bool IsSolidColor(gfx::SourceSurface* aSurface, BGRAColor aColor,
+ uint8_t aFuzz = 0);
+
+/**
+ * @returns true if every pixel in the range of rows specified by @aStartRow and
+ * @aRowCount of @aSurface is @aColor.
+ *
+ * If @aFuzz is nonzero, a tolerance of @aFuzz is allowed in each color
+ * component. This may be necessary for tests that involve JPEG images or
+ * downscaling.
+ */
+bool RowsAreSolidColor(gfx::SourceSurface* aSurface, int32_t aStartRow,
+ int32_t aRowCount, BGRAColor aColor, uint8_t aFuzz = 0);
+
+/**
+ * @returns true if every pixel in the rect specified by @aRect is @aColor.
+ *
+ * If @aFuzz is nonzero, a tolerance of @aFuzz is allowed in each color
+ * component. This may be necessary for tests that involve JPEG images or
+ * downscaling.
+ */
+bool RectIsSolidColor(gfx::SourceSurface* aSurface, const gfx::IntRect& aRect,
+ BGRAColor aColor, uint8_t aFuzz = 0);
+
+/**
+ * @returns true if the pixels in @aRow of @aSurface match the pixels given in
+ * @aPixels.
+ */
+bool RowHasPixels(gfx::SourceSurface* aSurface, int32_t aRow,
+ const std::vector<BGRAColor>& aPixels);
+
+// ExpectNoResume is an IResumable implementation for use by tests that expect
+// Resume() to never get called.
+class ExpectNoResume final : public IResumable {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ExpectNoResume, override)
+
+ void Resume() override { FAIL() << "Resume() should not get called"; }
+
+ private:
+ ~ExpectNoResume() override {}
+};
+
+// CountResumes is an IResumable implementation for use by tests that expect
+// Resume() to get called a certain number of times.
+class CountResumes : public IResumable {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CountResumes, override)
+
+ CountResumes() : mCount(0) {}
+
+ void Resume() override { mCount++; }
+ uint32_t Count() const { return mCount; }
+
+ private:
+ ~CountResumes() override {}
+
+ uint32_t mCount;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// SurfacePipe Helpers
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Creates a decoder with no data associated with, suitable for testing code
+ * that requires a decoder to initialize or to allocate surfaces but doesn't
+ * actually need the decoder to do any decoding.
+ *
+ * XXX(seth): We only need this because SurfaceSink defer to the decoder for
+ * surface allocation. Once all decoders use SurfacePipe we won't need to do
+ * that anymore and we can remove this function.
+ */
+already_AddRefed<Decoder> CreateTrivialDecoder();
+
+/**
+ * Creates a pipeline of SurfaceFilters from a list of Config structs and passes
+ * it to the provided lambda @aFunc. Assertions that the pipeline is constructly
+ * correctly and cleanup of any allocated surfaces is handled automatically.
+ *
+ * @param aDecoder The decoder to use for allocating surfaces.
+ * @param aFunc The lambda function to pass the filter pipeline to.
+ * @param aConfigs The configuration for the pipeline.
+ */
+template <typename Func, typename... Configs>
+void WithFilterPipeline(Decoder* aDecoder, Func aFunc, bool aFinish,
+ const Configs&... aConfigs) {
+ auto pipe = MakeUnique<typename detail::FilterPipeline<Configs...>::Type>();
+ nsresult rv = pipe->Configure(aConfigs...);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ aFunc(aDecoder, pipe.get());
+
+ if (aFinish) {
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ if (currentFrame) {
+ currentFrame->Finish();
+ }
+ }
+}
+
+template <typename Func, typename... Configs>
+void WithFilterPipeline(Decoder* aDecoder, Func aFunc,
+ const Configs&... aConfigs) {
+ WithFilterPipeline(aDecoder, aFunc, true, aConfigs...);
+}
+
+/**
+ * Creates a pipeline of SurfaceFilters from a list of Config structs and
+ * asserts that configuring it fails. Cleanup of any allocated surfaces is
+ * handled automatically.
+ *
+ * @param aDecoder The decoder to use for allocating surfaces.
+ * @param aConfigs The configuration for the pipeline.
+ */
+template <typename... Configs>
+void AssertConfiguringPipelineFails(Decoder* aDecoder,
+ const Configs&... aConfigs) {
+ auto pipe = MakeUnique<typename detail::FilterPipeline<Configs...>::Type>();
+ nsresult rv = pipe->Configure(aConfigs...);
+
+ // Callers expect configuring the pipeline to fail.
+ ASSERT_NS_FAILED(rv);
+
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ if (currentFrame) {
+ currentFrame->Finish();
+ }
+}
+
+/**
+ * Asserts that the provided filter pipeline is in the correct final state,
+ * which is to say, the entire surface has been written to (IsSurfaceFinished()
+ * returns true) and the invalid rects are as expected.
+ *
+ * @param aFilter The filter pipeline to check.
+ * @param aInputSpaceRect The expect invalid rect, in input space.
+ * @param aoutputSpaceRect The expect invalid rect, in output space.
+ */
+void AssertCorrectPipelineFinalState(SurfaceFilter* aFilter,
+ const gfx::IntRect& aInputSpaceRect,
+ const gfx::IntRect& aOutputSpaceRect);
+
+/**
+ * Checks a generated image for correctness. Reports any unexpected deviation
+ * from the expected image as GTest failures.
+ *
+ * @param aDecoder The decoder which contains the image. The decoder's current
+ * frame will be checked.
+ * @param aRect The region in the space of the output surface that the filter
+ * pipeline will actually write to. It's expected that pixels in
+ * this region are green, while pixels outside this region are
+ * transparent.
+ * @param aFuzz The amount of fuzz to use in pixel comparisons.
+ */
+void CheckGeneratedImage(Decoder* aDecoder, const gfx::IntRect& aRect,
+ uint8_t aFuzz = 0);
+
+/**
+ * Checks a generated surface for correctness. Reports any unexpected deviation
+ * from the expected image as GTest failures.
+ *
+ * @param aSurface The surface to check.
+ * @param aRect The region in the space of the output surface that the filter
+ * pipeline will actually write to.
+ * @param aInnerColor Check that pixels inside of aRect are this color.
+ * @param aOuterColor Check that pixels outside of aRect are this color.
+ * @param aFuzz The amount of fuzz to use in pixel comparisons.
+ */
+void CheckGeneratedSurface(gfx::SourceSurface* aSurface,
+ const gfx::IntRect& aRect,
+ const BGRAColor& aInnerColor,
+ const BGRAColor& aOuterColor, uint8_t aFuzz = 0);
+
+/**
+ * Tests the result of calling WritePixels() using the provided SurfaceFilter
+ * pipeline. The pipeline must be a normal (i.e., non-paletted) pipeline.
+ *
+ * The arguments are specified in the an order intended to minimize the number
+ * of arguments that most test cases need to pass.
+ *
+ * @param aDecoder The decoder whose current frame will be written to.
+ * @param aFilter The SurfaceFilter pipeline to use.
+ * @param aOutputRect The region in the space of the output surface that will be
+ * invalidated by the filter pipeline. Defaults to
+ * (0, 0, 100, 100).
+ * @param aInputRect The region in the space of the input image that will be
+ * invalidated by the filter pipeline. Defaults to
+ * (0, 0, 100, 100).
+ * @param aInputWriteRect The region in the space of the input image that the
+ * filter pipeline will allow writes to. Note the
+ * difference from @aInputRect: @aInputRect is the actual
+ * region invalidated, while @aInputWriteRect is the
+ * region that is written to. These can differ in cases
+ * where the input is not clipped to the size of the
+ * image. Defaults to the entire input rect.
+ * @param aOutputWriteRect The region in the space of the output surface that
+ * the filter pipeline will actually write to. It's
+ * expected that pixels in this region are green, while
+ * pixels outside this region are transparent. Defaults
+ * to the entire output rect.
+ */
+void CheckWritePixels(Decoder* aDecoder, SurfaceFilter* aFilter,
+ const Maybe<gfx::IntRect>& aOutputRect = Nothing(),
+ const Maybe<gfx::IntRect>& aInputRect = Nothing(),
+ const Maybe<gfx::IntRect>& aInputWriteRect = Nothing(),
+ const Maybe<gfx::IntRect>& aOutputWriteRect = Nothing(),
+ uint8_t aFuzz = 0);
+
+/**
+ * Tests the result of calling WritePixels() using the provided SurfaceFilter
+ * pipeline. Allows for control over the input color to write, and the expected
+ * output color.
+ * @see CheckWritePixels() for documentation of the arguments.
+ */
+void CheckTransformedWritePixels(
+ Decoder* aDecoder, SurfaceFilter* aFilter, const BGRAColor& aInputColor,
+ const BGRAColor& aOutputColor,
+ const Maybe<gfx::IntRect>& aOutputRect = Nothing(),
+ const Maybe<gfx::IntRect>& aInputRect = Nothing(),
+ const Maybe<gfx::IntRect>& aInputWriteRect = Nothing(),
+ const Maybe<gfx::IntRect>& aOutputWriteRect = Nothing(), uint8_t aFuzz = 0);
+
+///////////////////////////////////////////////////////////////////////////////
+// Decoder Helpers
+///////////////////////////////////////////////////////////////////////////////
+
+// Friend class of Decoder to access internals for tests.
+class MOZ_STACK_CLASS DecoderTestHelper final {
+ public:
+ explicit DecoderTestHelper(Decoder* aDecoder) : mDecoder(aDecoder) {}
+
+ void PostIsAnimated(FrameTimeout aTimeout) {
+ mDecoder->PostIsAnimated(aTimeout);
+ }
+
+ void PostFrameStop(Opacity aOpacity) { mDecoder->PostFrameStop(aOpacity); }
+
+ private:
+ Decoder* mDecoder;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Test Data
+///////////////////////////////////////////////////////////////////////////////
+
+ImageTestCase GreenPNGTestCase();
+ImageTestCase GreenGIFTestCase();
+ImageTestCase GreenJPGTestCase();
+ImageTestCase GreenBMPTestCase();
+ImageTestCase GreenICOTestCase();
+ImageTestCase GreenIconTestCase();
+ImageTestCase GreenWebPTestCase();
+ImageTestCase GreenAVIFTestCase();
+
+ImageTestCase NonzeroReservedAVIFTestCase();
+ImageTestCase MultipleColrAVIFTestCase();
+ImageTestCase Transparent10bit420AVIFTestCase();
+ImageTestCase Transparent10bit422AVIFTestCase();
+ImageTestCase Transparent10bit444AVIFTestCase();
+ImageTestCase Transparent12bit420AVIFTestCase();
+ImageTestCase Transparent12bit422AVIFTestCase();
+ImageTestCase Transparent12bit444AVIFTestCase();
+ImageTestCase Transparent8bit420AVIFTestCase();
+ImageTestCase Transparent8bit422AVIFTestCase();
+ImageTestCase Transparent8bit444AVIFTestCase();
+
+ImageTestCase Gray8bitLimitedRangeBT601AVIFTestCase();
+ImageTestCase Gray8bitLimitedRangeBT709AVIFTestCase();
+ImageTestCase Gray8bitLimitedRangeBT2020AVIFTestCase();
+ImageTestCase Gray8bitFullRangeBT601AVIFTestCase();
+ImageTestCase Gray8bitFullRangeBT709AVIFTestCase();
+ImageTestCase Gray8bitFullRangeBT2020AVIFTestCase();
+ImageTestCase Gray10bitLimitedRangeBT601AVIFTestCase();
+ImageTestCase Gray10bitLimitedRangeBT709AVIFTestCase();
+ImageTestCase Gray10bitLimitedRangeBT2020AVIFTestCase();
+ImageTestCase Gray10bitFullRangeBT601AVIFTestCase();
+ImageTestCase Gray10bitFullRangeBT709AVIFTestCase();
+ImageTestCase Gray10bitFullRangeBT2020AVIFTestCase();
+ImageTestCase Gray12bitLimitedRangeBT601AVIFTestCase();
+ImageTestCase Gray12bitLimitedRangeBT709AVIFTestCase();
+ImageTestCase Gray12bitLimitedRangeBT2020AVIFTestCase();
+ImageTestCase Gray12bitFullRangeBT601AVIFTestCase();
+ImageTestCase Gray12bitFullRangeBT709AVIFTestCase();
+ImageTestCase Gray12bitFullRangeBT2020AVIFTestCase();
+ImageTestCase Gray8bitLimitedRangeGrayscaleAVIFTestCase();
+ImageTestCase Gray8bitFullRangeGrayscaleAVIFTestCase();
+ImageTestCase Gray10bitLimitedRangeGrayscaleAVIFTestCase();
+ImageTestCase Gray10bitFullRangeGrayscaleAVIFTestCase();
+ImageTestCase Gray12bitLimitedRangeGrayscaleAVIFTestCase();
+ImageTestCase Gray12bitFullRangeGrayscaleAVIFTestCase();
+
+ImageTestCase StackCheckAVIFTestCase();
+
+ImageTestCase LargeWebPTestCase();
+ImageTestCase GreenWebPIccSrgbTestCase();
+
+ImageTestCase GreenFirstFrameAnimatedGIFTestCase();
+ImageTestCase GreenFirstFrameAnimatedPNGTestCase();
+ImageTestCase GreenFirstFrameAnimatedWebPTestCase();
+ImageTestCase GreenFirstFrameAnimatedAVIFTestCase();
+
+ImageTestCase BlendAnimatedGIFTestCase();
+ImageTestCase BlendAnimatedPNGTestCase();
+ImageTestCase BlendAnimatedWebPTestCase();
+ImageTestCase BlendAnimatedAVIFTestCase();
+
+ImageTestCase CorruptTestCase();
+ImageTestCase CorruptBMPWithTruncatedHeader();
+ImageTestCase CorruptICOWithBadBMPWidthTestCase();
+ImageTestCase CorruptICOWithBadBMPHeightTestCase();
+ImageTestCase CorruptICOWithBadBppTestCase();
+
+ImageTestCase TransparentPNGTestCase();
+ImageTestCase TransparentGIFTestCase();
+ImageTestCase TransparentWebPTestCase();
+ImageTestCase TransparentNoAlphaHeaderWebPTestCase();
+ImageTestCase FirstFramePaddingGIFTestCase();
+ImageTestCase TransparentIfWithinICOBMPTestCase(TestCaseFlags aFlags);
+ImageTestCase NoFrameDelayGIFTestCase();
+ImageTestCase ExtraImageSubBlocksAnimatedGIFTestCase();
+
+ImageTestCase TransparentBMPWhenBMPAlphaEnabledTestCase();
+ImageTestCase RLE4BMPTestCase();
+ImageTestCase RLE8BMPTestCase();
+
+ImageTestCase DownscaledPNGTestCase();
+ImageTestCase DownscaledGIFTestCase();
+ImageTestCase DownscaledJPGTestCase();
+ImageTestCase DownscaledBMPTestCase();
+ImageTestCase DownscaledICOTestCase();
+ImageTestCase DownscaledIconTestCase();
+ImageTestCase DownscaledWebPTestCase();
+ImageTestCase DownscaledTransparentICOWithANDMaskTestCase();
+
+ImageTestCase TruncatedSmallGIFTestCase();
+
+ImageTestCase LargeICOWithBMPTestCase();
+ImageTestCase LargeICOWithPNGTestCase();
+ImageTestCase GreenMultipleSizesICOTestCase();
+
+ImageTestCase PerfGrayJPGTestCase();
+ImageTestCase PerfCmykJPGTestCase();
+ImageTestCase PerfYCbCrJPGTestCase();
+ImageTestCase PerfRgbPNGTestCase();
+ImageTestCase PerfRgbAlphaPNGTestCase();
+ImageTestCase PerfGrayPNGTestCase();
+ImageTestCase PerfGrayAlphaPNGTestCase();
+ImageTestCase PerfRgbLosslessWebPTestCase();
+ImageTestCase PerfRgbAlphaLosslessWebPTestCase();
+ImageTestCase PerfRgbLossyWebPTestCase();
+ImageTestCase PerfRgbAlphaLossyWebPTestCase();
+ImageTestCase PerfRgbGIFTestCase();
+
+ImageTestCase CorruptAVIFTestCase();
+ImageTestCase DownscaledAVIFTestCase();
+ImageTestCase LargeAVIFTestCase();
+ImageTestCase MultiLayerAVIFTestCase();
+ImageTestCase TransparentAVIFTestCase();
+
+#ifdef MOZ_JXL
+ImageTestCase GreenJXLTestCase();
+ImageTestCase DownscaledJXLTestCase();
+ImageTestCase LargeJXLTestCase();
+ImageTestCase TransparentJXLTestCase();
+#endif
+
+ImageTestCase ExifResolutionTestCase();
+
+RefPtr<Image> TestCaseToDecodedImage(const ImageTestCase&);
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_test_gtest_Common_h
diff --git a/image/test/gtest/TestADAM7InterpolatingFilter.cpp b/image/test/gtest/TestADAM7InterpolatingFilter.cpp
new file mode 100644
index 0000000000..b2ae6b5a58
--- /dev/null
+++ b/image/test/gtest/TestADAM7InterpolatingFilter.cpp
@@ -0,0 +1,595 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <algorithm>
+#include <vector>
+
+#include "gtest/gtest.h"
+
+#include "mozilla/gfx/2D.h"
+#include "mozilla/Maybe.h"
+#include "Common.h"
+#include "Decoder.h"
+#include "DecoderFactory.h"
+#include "SourceBuffer.h"
+#include "SurfaceFilters.h"
+#include "SurfacePipe.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+using std::generate;
+using std::vector;
+
+template <typename Func>
+void WithADAM7InterpolatingFilter(const IntSize& aSize, Func aFunc) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(bool(decoder));
+
+ WithFilterPipeline(
+ decoder, std::forward<Func>(aFunc), ADAM7InterpolatingConfig{},
+ SurfaceConfig{decoder, aSize, SurfaceFormat::OS_RGBA, false});
+}
+
+void AssertConfiguringADAM7InterpolatingFilterFails(const IntSize& aSize) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(bool(decoder));
+
+ AssertConfiguringPipelineFails(
+ decoder, ADAM7InterpolatingConfig{},
+ SurfaceConfig{decoder, aSize, SurfaceFormat::OS_RGBA, false});
+}
+
+uint8_t InterpolateByte(uint8_t aByteA, uint8_t aByteB, float aWeight) {
+ return uint8_t(aByteA * aWeight + aByteB * (1.0f - aWeight));
+}
+
+BGRAColor InterpolateColors(BGRAColor aColor1, BGRAColor aColor2,
+ float aWeight) {
+ return BGRAColor(InterpolateByte(aColor1.mBlue, aColor2.mBlue, aWeight),
+ InterpolateByte(aColor1.mGreen, aColor2.mGreen, aWeight),
+ InterpolateByte(aColor1.mRed, aColor2.mRed, aWeight),
+ InterpolateByte(aColor1.mAlpha, aColor2.mAlpha, aWeight));
+}
+
+enum class ShouldInterpolate { eYes, eNo };
+
+BGRAColor HorizontallyInterpolatedPixel(uint32_t aCol, uint32_t aWidth,
+ const vector<float>& aWeights,
+ ShouldInterpolate aShouldInterpolate,
+ const vector<BGRAColor>& aColors) {
+ // We cycle through the vector of weights forever.
+ float weight = aWeights[aCol % aWeights.size()];
+
+ // Find the columns of the two final pixels for this set of weights.
+ uint32_t finalPixel1 = aCol - aCol % aWeights.size();
+ uint32_t finalPixel2 = finalPixel1 + aWeights.size();
+
+ // If |finalPixel2| is past the end of the row, that means that there is no
+ // final pixel after the pixel at |finalPixel1|. In that case, we just want to
+ // duplicate |finalPixel1|'s color until the end of the row. We can do that by
+ // setting |finalPixel2| equal to |finalPixel1| so that the interpolation has
+ // no effect.
+ if (finalPixel2 >= aWidth) {
+ finalPixel2 = finalPixel1;
+ }
+
+ // We cycle through the vector of colors forever (subject to the above
+ // constraint about the end of the row).
+ BGRAColor color1 = aColors[finalPixel1 % aColors.size()];
+ BGRAColor color2 = aColors[finalPixel2 % aColors.size()];
+
+ // If we're not interpolating, we treat all pixels which aren't final as
+ // transparent. Since the number of weights we have is equal to the stride
+ // between final pixels, we can check if |aCol| is a final pixel by checking
+ // whether |aCol| is a multiple of |aWeights.size()|.
+ if (aShouldInterpolate == ShouldInterpolate::eNo) {
+ return aCol % aWeights.size() == 0 ? color1 : BGRAColor::Transparent();
+ }
+
+ // Interpolate.
+ return InterpolateColors(color1, color2, weight);
+}
+
+vector<float>& InterpolationWeights(int32_t aStride) {
+ // Precalculated interpolation weights. These are used to interpolate
+ // between final pixels or between important rows. Although no interpolation
+ // is actually applied to the previous final pixel or important row value,
+ // the arrays still start with 1.0f, which is always skipped, primarily
+ // because otherwise |stride1Weights| would have zero elements.
+ static vector<float> stride8Weights = {1.0f, 7 / 8.0f, 6 / 8.0f,
+ 5 / 8.0f, 4 / 8.0f, 3 / 8.0f,
+ 2 / 8.0f, 1 / 8.0f};
+ static vector<float> stride4Weights = {1.0f, 3 / 4.0f, 2 / 4.0f, 1 / 4.0f};
+ static vector<float> stride2Weights = {1.0f, 1 / 2.0f};
+ static vector<float> stride1Weights = {1.0f};
+
+ switch (aStride) {
+ case 8:
+ return stride8Weights;
+ case 4:
+ return stride4Weights;
+ case 2:
+ return stride2Weights;
+ case 1:
+ return stride1Weights;
+ default:
+ MOZ_CRASH();
+ }
+}
+
+int32_t ImportantRowStride(uint8_t aPass) {
+ // The stride between important rows for each pass, with a dummy value for
+ // the nonexistent pass 0 and for pass 8, since the tests run an extra pass to
+ // make sure nothing breaks.
+ static int32_t strides[] = {1, 8, 8, 4, 4, 2, 2, 1, 1};
+
+ return strides[aPass];
+}
+
+size_t FinalPixelStride(uint8_t aPass) {
+ // The stride between the final pixels in important rows for each pass, with
+ // a dummy value for the nonexistent pass 0 and for pass 8, since the tests
+ // run an extra pass to make sure nothing breaks.
+ static size_t strides[] = {1, 8, 4, 4, 2, 2, 1, 1, 1};
+
+ return strides[aPass];
+}
+
+bool IsImportantRow(int32_t aRow, uint8_t aPass) {
+ return aRow % ImportantRowStride(aPass) == 0;
+}
+
+/**
+ * ADAM7 breaks up the image into 8x8 blocks. On each of the 7 passes, a new
+ * set of pixels in each block receives their final values, according to the
+ * following pattern:
+ *
+ * 1 6 4 6 2 6 4 6
+ * 7 7 7 7 7 7 7 7
+ * 5 6 5 6 5 6 5 6
+ * 7 7 7 7 7 7 7 7
+ * 3 6 4 6 3 6 4 6
+ * 7 7 7 7 7 7 7 7
+ * 5 6 5 6 5 6 5 6
+ * 7 7 7 7 7 7 7 7
+ *
+ * This function produces a row of pixels @aWidth wide, suitable for testing
+ * horizontal interpolation on pass @aPass. The pattern of pixels used is
+ * determined by @aPass and @aRow, which determine which pixels are final
+ * according to the table above, and @aColors, from which the pixel values
+ * are selected.
+ *
+ * There are two different behaviors: if |eNo| is passed for
+ * @aShouldInterpolate, non-final pixels are treated as transparent. If |eNo|
+ * is passed, non-final pixels get interpolated in from the surrounding final
+ * pixels. The intention is that |eNo| is passed to generate input which will
+ * be run through ADAM7InterpolatingFilter, and |eYes| is passed to generate
+ * reference data to check that the filter is performing horizontal
+ * interpolation correctly.
+ *
+ * This function does not perform vertical interpolation. Rows which aren't on
+ * the current pass are filled with transparent pixels.
+ *
+ * @return a vector<BGRAColor> representing a row of pixels.
+ */
+vector<BGRAColor> ADAM7HorizontallyInterpolatedRow(
+ uint8_t aPass, uint32_t aRow, uint32_t aWidth,
+ ShouldInterpolate aShouldInterpolate, const vector<BGRAColor>& aColors) {
+ EXPECT_GT(aPass, 0);
+ EXPECT_LE(aPass, 8);
+ EXPECT_GT(aColors.size(), 0u);
+
+ vector<BGRAColor> result(aWidth);
+
+ if (IsImportantRow(aRow, aPass)) {
+ vector<float>& weights = InterpolationWeights(FinalPixelStride(aPass));
+
+ // Compute the horizontally interpolated row.
+ uint32_t col = 0;
+ generate(result.begin(), result.end(), [&] {
+ return HorizontallyInterpolatedPixel(col++, aWidth, weights,
+ aShouldInterpolate, aColors);
+ });
+ } else {
+ // This is an unimportant row; just make the entire thing transparent.
+ generate(result.begin(), result.end(),
+ [] { return BGRAColor::Transparent(); });
+ }
+
+ EXPECT_EQ(result.size(), size_t(aWidth));
+
+ return result;
+}
+
+WriteState WriteUninterpolatedPixels(SurfaceFilter* aFilter,
+ const IntSize& aSize, uint8_t aPass,
+ const vector<BGRAColor>& aColors) {
+ WriteState result = WriteState::NEED_MORE_DATA;
+
+ for (int32_t row = 0; row < aSize.height; ++row) {
+ // Compute uninterpolated pixels for this row.
+ vector<BGRAColor> pixels = ADAM7HorizontallyInterpolatedRow(
+ aPass, row, aSize.width, ShouldInterpolate::eNo, aColors);
+
+ // Write them to the surface.
+ auto pixelIterator = pixels.cbegin();
+ result = aFilter->WritePixelsToRow<uint32_t>(
+ [&] { return AsVariant((*pixelIterator++).AsPixel()); });
+
+ if (result != WriteState::NEED_MORE_DATA) {
+ break;
+ }
+ }
+
+ return result;
+}
+
+bool CheckHorizontallyInterpolatedImage(image::Decoder* aDecoder,
+ const IntSize& aSize, uint8_t aPass,
+ const vector<BGRAColor>& aColors) {
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+
+ for (int32_t row = 0; row < aSize.height; ++row) {
+ if (!IsImportantRow(row, aPass)) {
+ continue; // Don't check rows which aren't important on this pass.
+ }
+
+ // Compute the expected pixels, *with* interpolation to match what the
+ // filter should have done.
+ vector<BGRAColor> expectedPixels = ADAM7HorizontallyInterpolatedRow(
+ aPass, row, aSize.width, ShouldInterpolate::eYes, aColors);
+
+ if (!RowHasPixels(surface, row, expectedPixels)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void CheckHorizontalInterpolation(const IntSize& aSize,
+ const vector<BGRAColor>& aColors) {
+ const IntRect surfaceRect(IntPoint(0, 0), aSize);
+
+ WithADAM7InterpolatingFilter(
+ aSize, [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // We check horizontal interpolation behavior for each pass
+ // individually. In addition to the normal 7 passes that ADAM7 includes,
+ // we also check an eighth pass to verify that nothing breaks if extra
+ // data is written.
+ for (uint8_t pass = 1; pass <= 8; ++pass) {
+ // Write our color pattern to the surface. We don't perform any
+ // interpolation when writing to the filter so that we can check that
+ // the filter itself *does*.
+ WriteState result =
+ WriteUninterpolatedPixels(aFilter, aSize, pass, aColors);
+
+ EXPECT_EQ(WriteState::FINISHED, result);
+ AssertCorrectPipelineFinalState(aFilter, surfaceRect, surfaceRect);
+
+ // Check that the generated image matches the expected pattern, with
+ // interpolation applied.
+ EXPECT_TRUE(CheckHorizontallyInterpolatedImage(aDecoder, aSize, pass,
+ aColors));
+
+ // Prepare for the next pass.
+ aFilter->ResetToFirstRow();
+ }
+ });
+}
+
+BGRAColor ADAM7RowColor(int32_t aRow, uint8_t aPass,
+ const vector<BGRAColor>& aColors) {
+ EXPECT_LT(0, aPass);
+ EXPECT_GE(8, aPass);
+ EXPECT_LT(0u, aColors.size());
+
+ // If this is an important row, select the color from the provided vector of
+ // colors, which we cycle through infinitely. If not, just fill the row with
+ // transparent pixels.
+ return IsImportantRow(aRow, aPass) ? aColors[aRow % aColors.size()]
+ : BGRAColor::Transparent();
+}
+
+WriteState WriteRowColorPixels(SurfaceFilter* aFilter, const IntSize& aSize,
+ uint8_t aPass,
+ const vector<BGRAColor>& aColors) {
+ WriteState result = WriteState::NEED_MORE_DATA;
+
+ for (int32_t row = 0; row < aSize.height; ++row) {
+ const uint32_t color = ADAM7RowColor(row, aPass, aColors).AsPixel();
+
+ // Fill the surface with |color| pixels.
+ result =
+ aFilter->WritePixelsToRow<uint32_t>([&] { return AsVariant(color); });
+
+ if (result != WriteState::NEED_MORE_DATA) {
+ break;
+ }
+ }
+
+ return result;
+}
+
+bool CheckVerticallyInterpolatedImage(image::Decoder* aDecoder,
+ const IntSize& aSize, uint8_t aPass,
+ const vector<BGRAColor>& aColors) {
+ vector<float>& weights = InterpolationWeights(ImportantRowStride(aPass));
+
+ for (int32_t row = 0; row < aSize.height; ++row) {
+ // Vertically interpolation takes place between two important rows. The
+ // separation between the important rows is determined by the stride of this
+ // pass. When there is no "next" important row because we'd run off the
+ // bottom of the image, we use the same row for both. This matches
+ // ADAM7InterpolatingFilter's behavior of duplicating the last important row
+ // since there isn't another important row to vertically interpolate it
+ // with.
+ const int32_t stride = ImportantRowStride(aPass);
+ const int32_t prevImportantRow = row - row % stride;
+ const int32_t maybeNextImportantRow = prevImportantRow + stride;
+ const int32_t nextImportantRow = maybeNextImportantRow < aSize.height
+ ? maybeNextImportantRow
+ : prevImportantRow;
+
+ // Retrieve the colors for the important rows we're going to interpolate.
+ const BGRAColor prevImportantRowColor =
+ ADAM7RowColor(prevImportantRow, aPass, aColors);
+ const BGRAColor nextImportantRowColor =
+ ADAM7RowColor(nextImportantRow, aPass, aColors);
+
+ // The weight we'll use for interpolation is also determined by the stride.
+ // A row halfway between two important rows should have pixels that have a
+ // 50% contribution from each of the important rows, for example.
+ const float weight = weights[row % stride];
+ const BGRAColor interpolatedColor =
+ InterpolateColors(prevImportantRowColor, nextImportantRowColor, weight);
+
+ // Generate a row of expected pixels. Every pixel in the row is always the
+ // same color since we're only testing vertical interpolation between
+ // solid-colored rows.
+ vector<BGRAColor> expectedPixels(aSize.width);
+ generate(expectedPixels.begin(), expectedPixels.end(),
+ [&] { return interpolatedColor; });
+
+ // Check that the pixels match.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ if (!RowHasPixels(surface, row, expectedPixels)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void CheckVerticalInterpolation(const IntSize& aSize,
+ const vector<BGRAColor>& aColors) {
+ const IntRect surfaceRect(IntPoint(0, 0), aSize);
+
+ WithADAM7InterpolatingFilter(aSize, [&](image::Decoder* aDecoder,
+ SurfaceFilter* aFilter) {
+ for (uint8_t pass = 1; pass <= 8; ++pass) {
+ // Write a pattern of rows to the surface. Important rows will receive a
+ // color selected from |aColors|; unimportant rows will be transparent.
+ WriteState result = WriteRowColorPixels(aFilter, aSize, pass, aColors);
+
+ EXPECT_EQ(WriteState::FINISHED, result);
+ AssertCorrectPipelineFinalState(aFilter, surfaceRect, surfaceRect);
+
+ // Check that the generated image matches the expected pattern, with
+ // interpolation applied.
+ EXPECT_TRUE(
+ CheckVerticallyInterpolatedImage(aDecoder, aSize, pass, aColors));
+
+ // Prepare for the next pass.
+ aFilter->ResetToFirstRow();
+ }
+ });
+}
+
+void CheckInterpolation(const IntSize& aSize,
+ const vector<BGRAColor>& aColors) {
+ CheckHorizontalInterpolation(aSize, aColors);
+ CheckVerticalInterpolation(aSize, aColors);
+}
+
+void CheckADAM7InterpolatingWritePixels(const IntSize& aSize) {
+ // This test writes 8 passes of green pixels (the seven ADAM7 passes, plus one
+ // extra to make sure nothing goes wrong if we write too much input) and
+ // verifies that the output is a solid green surface each time. Because all
+ // the pixels are the same color, interpolation doesn't matter; we test the
+ // correctness of the interpolation algorithm itself separately.
+ WithADAM7InterpolatingFilter(
+ aSize, [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ IntRect rect(IntPoint(0, 0), aSize);
+
+ for (int32_t pass = 1; pass <= 8; ++pass) {
+ // We only actually write up to the last important row for each pass,
+ // because that row unambiguously determines the remaining rows.
+ const int32_t lastRow = aSize.height - 1;
+ const int32_t lastImportantRow =
+ lastRow - (lastRow % ImportantRowStride(pass));
+ const IntRect inputWriteRect(0, 0, aSize.width, lastImportantRow + 1);
+
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(rect),
+ /* aInputRect = */ Some(rect),
+ /* aInputWriteRect = */ Some(inputWriteRect));
+
+ aFilter->ResetToFirstRow();
+ EXPECT_FALSE(aFilter->IsSurfaceFinished());
+ Maybe<SurfaceInvalidRect> invalidRect = aFilter->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isNothing());
+ }
+ });
+}
+
+TEST(ImageADAM7InterpolatingFilter, WritePixels100_100)
+{ CheckADAM7InterpolatingWritePixels(IntSize(100, 100)); }
+
+TEST(ImageADAM7InterpolatingFilter, WritePixels99_99)
+{ CheckADAM7InterpolatingWritePixels(IntSize(99, 99)); }
+
+TEST(ImageADAM7InterpolatingFilter, WritePixels66_33)
+{ CheckADAM7InterpolatingWritePixels(IntSize(66, 33)); }
+
+TEST(ImageADAM7InterpolatingFilter, WritePixels33_66)
+{ CheckADAM7InterpolatingWritePixels(IntSize(33, 66)); }
+
+TEST(ImageADAM7InterpolatingFilter, WritePixels15_15)
+{ CheckADAM7InterpolatingWritePixels(IntSize(15, 15)); }
+
+TEST(ImageADAM7InterpolatingFilter, WritePixels9_9)
+{ CheckADAM7InterpolatingWritePixels(IntSize(9, 9)); }
+
+TEST(ImageADAM7InterpolatingFilter, WritePixels8_8)
+{ CheckADAM7InterpolatingWritePixels(IntSize(8, 8)); }
+
+TEST(ImageADAM7InterpolatingFilter, WritePixels7_7)
+{ CheckADAM7InterpolatingWritePixels(IntSize(7, 7)); }
+
+TEST(ImageADAM7InterpolatingFilter, WritePixels3_3)
+{ CheckADAM7InterpolatingWritePixels(IntSize(3, 3)); }
+
+TEST(ImageADAM7InterpolatingFilter, WritePixels1_1)
+{ CheckADAM7InterpolatingWritePixels(IntSize(1, 1)); }
+
+TEST(ImageADAM7InterpolatingFilter, TrivialInterpolation48_48)
+{ CheckInterpolation(IntSize(48, 48), {BGRAColor::Green()}); }
+
+TEST(ImageADAM7InterpolatingFilter, InterpolationOutput33_17)
+{
+ // We check interpolation using irregular patterns to make sure that the
+ // interpolation will look different for different passes.
+ CheckInterpolation(
+ IntSize(33, 17),
+ {BGRAColor::Green(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Blue(), BGRAColor::Blue(), BGRAColor::Blue(),
+ BGRAColor::Red(), BGRAColor::Green(), BGRAColor::Red(),
+ BGRAColor::Red(), BGRAColor::Blue(), BGRAColor::Blue(),
+ BGRAColor::Green(), BGRAColor::Blue(), BGRAColor::Red(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Red(), BGRAColor::Red(), BGRAColor::Blue(),
+ BGRAColor::Blue(), BGRAColor::Blue(), BGRAColor::Red(),
+ BGRAColor::Green(), BGRAColor::Green(), BGRAColor::Blue(),
+ BGRAColor::Red(), BGRAColor::Blue()});
+}
+
+TEST(ImageADAM7InterpolatingFilter, InterpolationOutput32_16)
+{
+ CheckInterpolation(
+ IntSize(32, 16),
+ {BGRAColor::Green(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Blue(), BGRAColor::Blue(), BGRAColor::Blue(),
+ BGRAColor::Red(), BGRAColor::Green(), BGRAColor::Red(),
+ BGRAColor::Red(), BGRAColor::Blue(), BGRAColor::Blue(),
+ BGRAColor::Green(), BGRAColor::Blue(), BGRAColor::Red(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Red(), BGRAColor::Red(), BGRAColor::Blue(),
+ BGRAColor::Blue(), BGRAColor::Blue(), BGRAColor::Red(),
+ BGRAColor::Green(), BGRAColor::Green(), BGRAColor::Blue(),
+ BGRAColor::Red(), BGRAColor::Blue()});
+}
+
+TEST(ImageADAM7InterpolatingFilter, InterpolationOutput31_15)
+{
+ CheckInterpolation(
+ IntSize(31, 15),
+ {BGRAColor::Green(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Blue(), BGRAColor::Blue(), BGRAColor::Blue(),
+ BGRAColor::Red(), BGRAColor::Green(), BGRAColor::Red(),
+ BGRAColor::Red(), BGRAColor::Blue(), BGRAColor::Blue(),
+ BGRAColor::Green(), BGRAColor::Blue(), BGRAColor::Red(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Red(), BGRAColor::Red(), BGRAColor::Blue(),
+ BGRAColor::Blue(), BGRAColor::Blue(), BGRAColor::Red(),
+ BGRAColor::Green(), BGRAColor::Green(), BGRAColor::Blue(),
+ BGRAColor::Red(), BGRAColor::Blue()});
+}
+
+TEST(ImageADAM7InterpolatingFilter, InterpolationOutput17_33)
+{
+ CheckInterpolation(IntSize(17, 33),
+ {BGRAColor::Green(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Blue(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Green(), BGRAColor::Red(), BGRAColor::Red(),
+ BGRAColor::Blue()});
+}
+
+TEST(ImageADAM7InterpolatingFilter, InterpolationOutput16_32)
+{
+ CheckInterpolation(IntSize(16, 32),
+ {BGRAColor::Green(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Blue(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Green(), BGRAColor::Red(), BGRAColor::Red(),
+ BGRAColor::Blue()});
+}
+
+TEST(ImageADAM7InterpolatingFilter, InterpolationOutput15_31)
+{
+ CheckInterpolation(IntSize(15, 31),
+ {BGRAColor::Green(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Blue(),
+ BGRAColor::Blue(), BGRAColor::Red(), BGRAColor::Green(),
+ BGRAColor::Green(), BGRAColor::Red(), BGRAColor::Red(),
+ BGRAColor::Blue()});
+}
+
+TEST(ImageADAM7InterpolatingFilter, InterpolationOutput9_9)
+{
+ CheckInterpolation(IntSize(9, 9),
+ {BGRAColor::Blue(), BGRAColor::Blue(), BGRAColor::Red(),
+ BGRAColor::Green(), BGRAColor::Green(), BGRAColor::Red(),
+ BGRAColor::Red(), BGRAColor::Blue()});
+}
+
+TEST(ImageADAM7InterpolatingFilter, InterpolationOutput8_8)
+{
+ CheckInterpolation(IntSize(8, 8),
+ {BGRAColor::Blue(), BGRAColor::Blue(), BGRAColor::Red(),
+ BGRAColor::Green(), BGRAColor::Green(), BGRAColor::Red(),
+ BGRAColor::Red(), BGRAColor::Blue()});
+}
+
+TEST(ImageADAM7InterpolatingFilter, InterpolationOutput7_7)
+{
+ CheckInterpolation(IntSize(7, 7),
+ {BGRAColor::Blue(), BGRAColor::Blue(), BGRAColor::Red(),
+ BGRAColor::Green(), BGRAColor::Green(), BGRAColor::Red(),
+ BGRAColor::Red(), BGRAColor::Blue()});
+}
+
+TEST(ImageADAM7InterpolatingFilter, InterpolationOutput3_3)
+{
+ CheckInterpolation(IntSize(3, 3), {BGRAColor::Green(), BGRAColor::Red(),
+ BGRAColor::Blue(), BGRAColor::Red()});
+}
+
+TEST(ImageADAM7InterpolatingFilter, InterpolationOutput1_1)
+{ CheckInterpolation(IntSize(1, 1), {BGRAColor::Blue()}); }
+
+TEST(ImageADAM7InterpolatingFilter, ADAM7InterpolationFailsFor0_0)
+{
+ // A 0x0 input size is invalid, so configuration should fail.
+ AssertConfiguringADAM7InterpolatingFilterFails(IntSize(0, 0));
+}
+
+TEST(ImageADAM7InterpolatingFilter, ADAM7InterpolationFailsForMinus1_Minus1)
+{
+ // A negative input size is invalid, so configuration should fail.
+ AssertConfiguringADAM7InterpolatingFilterFails(IntSize(-1, -1));
+}
diff --git a/image/test/gtest/TestAnimationFrameBuffer.cpp b/image/test/gtest/TestAnimationFrameBuffer.cpp
new file mode 100644
index 0000000000..78186e5066
--- /dev/null
+++ b/image/test/gtest/TestAnimationFrameBuffer.cpp
@@ -0,0 +1,895 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <utility>
+
+#include "AnimationFrameBuffer.h"
+#include "Common.h"
+#include "gtest/gtest.h"
+
+using namespace mozilla;
+using namespace mozilla::image;
+
+static already_AddRefed<imgFrame> CreateEmptyFrame(
+ const gfx::IntSize& aSize = gfx::IntSize(1, 1),
+ const gfx::IntRect& aFrameRect = gfx::IntRect(0, 0, 1, 1),
+ bool aCanRecycle = true) {
+ RefPtr<imgFrame> frame = new imgFrame();
+ AnimationParams animParams{aFrameRect, FrameTimeout::Forever(),
+ /* aFrameNum */ 1, BlendMethod::OVER,
+ DisposalMethod::NOT_SPECIFIED};
+ nsresult rv =
+ frame->InitForDecoder(aSize, mozilla::gfx::SurfaceFormat::OS_RGBA, false,
+ Some(animParams), aCanRecycle);
+ EXPECT_NS_SUCCEEDED(rv);
+ RawAccessFrameRef frameRef = frame->RawAccessRef();
+ // Normally the blend animation filter would set the dirty rect, but since
+ // we aren't producing an actual animation here, we need to fake it.
+ frame->SetDirtyRect(aFrameRect);
+ frame->Finish();
+ return frame.forget();
+}
+
+static bool ReinitForRecycle(RawAccessFrameRef& aFrame) {
+ if (!aFrame) {
+ return false;
+ }
+
+ AnimationParams animParams{aFrame->GetRect(), FrameTimeout::Forever(),
+ /* aFrameNum */ 1, BlendMethod::OVER,
+ DisposalMethod::NOT_SPECIFIED};
+ return NS_SUCCEEDED(aFrame->InitForDecoderRecycle(animParams));
+}
+
+static void PrepareForDiscardingQueue(AnimationFrameRetainedBuffer& aQueue) {
+ ASSERT_EQ(size_t(0), aQueue.Size());
+ ASSERT_LT(size_t(1), aQueue.Batch());
+
+ AnimationFrameBuffer::InsertStatus status = aQueue.Insert(CreateEmptyFrame());
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::CONTINUE, status);
+
+ while (true) {
+ status = aQueue.Insert(CreateEmptyFrame());
+ bool restartDecoder = aQueue.AdvanceTo(aQueue.Size() - 1);
+ EXPECT_FALSE(restartDecoder);
+
+ if (status == AnimationFrameBuffer::InsertStatus::DISCARD_CONTINUE) {
+ break;
+ }
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::CONTINUE, status);
+ }
+
+ EXPECT_EQ(aQueue.Threshold(), aQueue.Size());
+}
+
+static void VerifyDiscardingQueueContents(
+ AnimationFrameDiscardingQueue& aQueue) {
+ auto frames = aQueue.Display();
+ for (auto i : frames) {
+ EXPECT_TRUE(i != nullptr);
+ }
+}
+
+static void VerifyInsertInternal(AnimationFrameBuffer& aQueue,
+ imgFrame* aFrame) {
+ // Determine the frame index where we just inserted the frame.
+ size_t frameIndex;
+ if (aQueue.MayDiscard()) {
+ const AnimationFrameDiscardingQueue& queue =
+ *static_cast<AnimationFrameDiscardingQueue*>(&aQueue);
+ frameIndex = queue.PendingInsert() == 0 ? queue.Size() - 1
+ : queue.PendingInsert() - 1;
+ } else {
+ ASSERT_FALSE(aQueue.SizeKnown());
+ frameIndex = aQueue.Size() - 1;
+ }
+
+ // Make sure we can get the frame from that index.
+ RefPtr<imgFrame> frame = aQueue.Get(frameIndex, false);
+ EXPECT_EQ(aFrame, frame.get());
+}
+
+static void VerifyAdvance(AnimationFrameBuffer& aQueue, size_t aExpectedFrame,
+ bool aExpectedRestartDecoder) {
+ RefPtr<imgFrame> oldFrame;
+ size_t totalRecycled;
+ if (aQueue.IsRecycling()) {
+ AnimationFrameRecyclingQueue& queue =
+ *static_cast<AnimationFrameRecyclingQueue*>(&aQueue);
+ oldFrame = queue.Get(queue.Displayed(), false);
+ totalRecycled = queue.Recycle().size();
+ }
+
+ bool restartDecoder = aQueue.AdvanceTo(aExpectedFrame);
+ EXPECT_EQ(aExpectedRestartDecoder, restartDecoder);
+
+ if (aQueue.IsRecycling()) {
+ const AnimationFrameRecyclingQueue& queue =
+ *static_cast<AnimationFrameRecyclingQueue*>(&aQueue);
+ EXPECT_FALSE(queue.Recycle().back().mDirtyRect.IsEmpty());
+ EXPECT_TRUE(
+ queue.Recycle().back().mDirtyRect.Contains(oldFrame->GetDirtyRect()));
+ EXPECT_EQ(totalRecycled + 1, queue.Recycle().size());
+ EXPECT_EQ(oldFrame.get(), queue.Recycle().back().mFrame.get());
+ }
+}
+
+static void VerifyInsertAndAdvance(
+ AnimationFrameBuffer& aQueue, size_t aExpectedFrame,
+ AnimationFrameBuffer::InsertStatus aExpectedStatus) {
+ // Insert the decoded frame.
+ RefPtr<imgFrame> frame = CreateEmptyFrame();
+ AnimationFrameBuffer::InsertStatus status =
+ aQueue.Insert(RefPtr<imgFrame>(frame));
+ EXPECT_EQ(aExpectedStatus, status);
+ EXPECT_TRUE(aQueue.IsLastInsertedFrame(frame));
+ VerifyInsertInternal(aQueue, frame);
+
+ // Advance the display frame.
+ bool expectedRestartDecoder =
+ aExpectedStatus == AnimationFrameBuffer::InsertStatus::YIELD;
+ VerifyAdvance(aQueue, aExpectedFrame, expectedRestartDecoder);
+}
+
+static void VerifyMarkComplete(
+ AnimationFrameBuffer& aQueue, bool aExpectedContinue,
+ const gfx::IntRect& aRefreshArea = gfx::IntRect(0, 0, 1, 1)) {
+ if (aQueue.IsRecycling() && !aQueue.SizeKnown()) {
+ const AnimationFrameRecyclingQueue& queue =
+ *static_cast<AnimationFrameRecyclingQueue*>(&aQueue);
+ EXPECT_EQ(queue.FirstFrame()->GetRect(), queue.FirstFrameRefreshArea());
+ }
+
+ bool keepDecoding = aQueue.MarkComplete(aRefreshArea);
+ EXPECT_EQ(aExpectedContinue, keepDecoding);
+
+ if (aQueue.IsRecycling()) {
+ const AnimationFrameRecyclingQueue& queue =
+ *static_cast<AnimationFrameRecyclingQueue*>(&aQueue);
+ EXPECT_EQ(aRefreshArea, queue.FirstFrameRefreshArea());
+ }
+}
+
+static void VerifyInsert(AnimationFrameBuffer& aQueue,
+ AnimationFrameBuffer::InsertStatus aExpectedStatus) {
+ RefPtr<imgFrame> frame = CreateEmptyFrame();
+ AnimationFrameBuffer::InsertStatus status =
+ aQueue.Insert(RefPtr<imgFrame>(frame));
+ EXPECT_EQ(aExpectedStatus, status);
+ EXPECT_TRUE(aQueue.IsLastInsertedFrame(frame));
+ VerifyInsertInternal(aQueue, frame);
+}
+
+static void VerifyReset(AnimationFrameBuffer& aQueue, bool aExpectedContinue,
+ const imgFrame* aFirstFrame) {
+ bool keepDecoding = aQueue.Reset();
+ EXPECT_EQ(aExpectedContinue, keepDecoding);
+ EXPECT_EQ(aQueue.Batch() * 2, aQueue.PendingDecode());
+ EXPECT_EQ(aFirstFrame, aQueue.Get(0, true));
+
+ if (!aQueue.MayDiscard()) {
+ const AnimationFrameRetainedBuffer& queue =
+ *static_cast<AnimationFrameRetainedBuffer*>(&aQueue);
+ EXPECT_EQ(aFirstFrame, queue.Frames()[0].get());
+ EXPECT_EQ(aFirstFrame, aQueue.Get(0, false));
+ } else {
+ const AnimationFrameDiscardingQueue& queue =
+ *static_cast<AnimationFrameDiscardingQueue*>(&aQueue);
+ EXPECT_EQ(size_t(0), queue.PendingInsert());
+ EXPECT_EQ(size_t(0), queue.Display().size());
+ EXPECT_EQ(aFirstFrame, queue.FirstFrame());
+ EXPECT_EQ(nullptr, aQueue.Get(0, false));
+ }
+}
+
+class ImageAnimationFrameBuffer : public ::testing::Test {
+ public:
+ ImageAnimationFrameBuffer() {}
+
+ private:
+ AutoInitializeImageLib mInit;
+};
+
+TEST_F(ImageAnimationFrameBuffer, RetainedInitialState) {
+ const size_t kThreshold = 800;
+ const size_t kBatch = 100;
+ AnimationFrameRetainedBuffer buffer(kThreshold, kBatch, 0);
+
+ EXPECT_EQ(kThreshold, buffer.Threshold());
+ EXPECT_EQ(kBatch, buffer.Batch());
+ EXPECT_EQ(size_t(0), buffer.Displayed());
+ EXPECT_EQ(kBatch * 2, buffer.PendingDecode());
+ EXPECT_EQ(size_t(0), buffer.PendingAdvance());
+ EXPECT_FALSE(buffer.MayDiscard());
+ EXPECT_FALSE(buffer.SizeKnown());
+ EXPECT_EQ(size_t(0), buffer.Size());
+}
+
+TEST_F(ImageAnimationFrameBuffer, ThresholdTooSmall) {
+ const size_t kThreshold = 0;
+ const size_t kBatch = 10;
+ AnimationFrameRetainedBuffer buffer(kThreshold, kBatch, 0);
+
+ EXPECT_EQ(kBatch * 2 + 1, buffer.Threshold());
+ EXPECT_EQ(kBatch, buffer.Batch());
+ EXPECT_EQ(kBatch * 2, buffer.PendingDecode());
+ EXPECT_EQ(size_t(0), buffer.PendingAdvance());
+}
+
+TEST_F(ImageAnimationFrameBuffer, BatchTooSmall) {
+ const size_t kThreshold = 10;
+ const size_t kBatch = 0;
+ AnimationFrameRetainedBuffer buffer(kThreshold, kBatch, 0);
+
+ EXPECT_EQ(kThreshold, buffer.Threshold());
+ EXPECT_EQ(size_t(1), buffer.Batch());
+ EXPECT_EQ(size_t(2), buffer.PendingDecode());
+ EXPECT_EQ(size_t(0), buffer.PendingAdvance());
+}
+
+TEST_F(ImageAnimationFrameBuffer, BatchTooBig) {
+ const size_t kThreshold = 50;
+ const size_t kBatch = SIZE_MAX;
+ AnimationFrameRetainedBuffer buffer(kThreshold, kBatch, 0);
+
+ // The rounding is important here (e.g. SIZE_MAX/4 * 2 != SIZE_MAX/2).
+ EXPECT_EQ(SIZE_MAX / 4, buffer.Batch());
+ EXPECT_EQ(buffer.Batch() * 2 + 1, buffer.Threshold());
+ EXPECT_EQ(buffer.Batch() * 2, buffer.PendingDecode());
+ EXPECT_EQ(size_t(0), buffer.PendingAdvance());
+}
+
+TEST_F(ImageAnimationFrameBuffer, FinishUnderBatchAndThreshold) {
+ const size_t kThreshold = 30;
+ const size_t kBatch = 10;
+ AnimationFrameRetainedBuffer buffer(kThreshold, kBatch, 0);
+ const auto& frames = buffer.Frames();
+
+ EXPECT_EQ(kBatch * 2, buffer.PendingDecode());
+
+ RefPtr<imgFrame> firstFrame;
+ for (size_t i = 0; i < 5; ++i) {
+ RefPtr<imgFrame> frame = CreateEmptyFrame();
+ auto status = buffer.Insert(RefPtr<imgFrame>(frame));
+ EXPECT_EQ(status, AnimationFrameBuffer::InsertStatus::CONTINUE);
+ EXPECT_FALSE(buffer.SizeKnown());
+ EXPECT_EQ(buffer.Size(), i + 1);
+
+ if (i == 4) {
+ EXPECT_EQ(size_t(15), buffer.PendingDecode());
+ bool keepDecoding = buffer.MarkComplete(gfx::IntRect(0, 0, 1, 1));
+ EXPECT_FALSE(keepDecoding);
+ EXPECT_TRUE(buffer.SizeKnown());
+ EXPECT_EQ(size_t(0), buffer.PendingDecode());
+ EXPECT_FALSE(buffer.HasRedecodeError());
+ }
+
+ EXPECT_FALSE(buffer.MayDiscard());
+
+ imgFrame* gotFrame = buffer.Get(i, false);
+ EXPECT_EQ(frame.get(), gotFrame);
+ ASSERT_EQ(i + 1, frames.Length());
+ EXPECT_EQ(frame.get(), frames[i].get());
+
+ if (i == 0) {
+ firstFrame = std::move(frame);
+ EXPECT_EQ(size_t(0), buffer.Displayed());
+ } else {
+ EXPECT_EQ(i - 1, buffer.Displayed());
+ bool restartDecoder = buffer.AdvanceTo(i);
+ EXPECT_FALSE(restartDecoder);
+ EXPECT_EQ(i, buffer.Displayed());
+ }
+
+ gotFrame = buffer.Get(0, false);
+ EXPECT_EQ(firstFrame.get(), gotFrame);
+ }
+
+ // Loop again over the animation and make sure it is still all there.
+ for (size_t i = 0; i < frames.Length(); ++i) {
+ EXPECT_TRUE(buffer.Get(i, false) != nullptr);
+
+ bool restartDecoder = buffer.AdvanceTo(i);
+ EXPECT_FALSE(restartDecoder);
+ }
+}
+
+TEST_F(ImageAnimationFrameBuffer, FinishMultipleBatchesUnderThreshold) {
+ const size_t kThreshold = 30;
+ const size_t kBatch = 2;
+ AnimationFrameRetainedBuffer buffer(kThreshold, kBatch, 0);
+ const auto& frames = buffer.Frames();
+
+ EXPECT_EQ(kBatch * 2, buffer.PendingDecode());
+
+ // Add frames until it tells us to stop.
+ AnimationFrameBuffer::InsertStatus status;
+ do {
+ status = buffer.Insert(CreateEmptyFrame());
+ EXPECT_FALSE(buffer.SizeKnown());
+ EXPECT_FALSE(buffer.MayDiscard());
+ } while (status == AnimationFrameBuffer::InsertStatus::CONTINUE);
+
+ EXPECT_EQ(size_t(0), buffer.PendingDecode());
+ EXPECT_EQ(size_t(4), frames.Length());
+ EXPECT_EQ(status, AnimationFrameBuffer::InsertStatus::YIELD);
+
+ // Progress through the animation until it lets us decode again.
+ bool restartDecoder = false;
+ size_t i = 0;
+ do {
+ EXPECT_TRUE(buffer.Get(i, false) != nullptr);
+ if (i > 0) {
+ restartDecoder = buffer.AdvanceTo(i);
+ }
+ ++i;
+ } while (!restartDecoder);
+
+ EXPECT_EQ(size_t(2), buffer.PendingDecode());
+ EXPECT_EQ(size_t(2), buffer.Displayed());
+
+ // Add the last frame.
+ status = buffer.Insert(CreateEmptyFrame());
+ EXPECT_EQ(status, AnimationFrameBuffer::InsertStatus::CONTINUE);
+ bool keepDecoding = buffer.MarkComplete(gfx::IntRect(0, 0, 1, 1));
+ EXPECT_FALSE(keepDecoding);
+ EXPECT_TRUE(buffer.SizeKnown());
+ EXPECT_EQ(size_t(0), buffer.PendingDecode());
+ EXPECT_EQ(size_t(5), frames.Length());
+ EXPECT_FALSE(buffer.HasRedecodeError());
+
+ // Finish progressing through the animation.
+ for (; i < frames.Length(); ++i) {
+ EXPECT_TRUE(buffer.Get(i, false) != nullptr);
+ restartDecoder = buffer.AdvanceTo(i);
+ EXPECT_FALSE(restartDecoder);
+ }
+
+ // Loop again over the animation and make sure it is still all there.
+ for (i = 0; i < frames.Length(); ++i) {
+ EXPECT_TRUE(buffer.Get(i, false) != nullptr);
+ restartDecoder = buffer.AdvanceTo(i);
+ EXPECT_FALSE(restartDecoder);
+ }
+
+ // Loop to the third frame and then reset the animation.
+ for (i = 0; i < 3; ++i) {
+ EXPECT_TRUE(buffer.Get(i, false) != nullptr);
+ restartDecoder = buffer.AdvanceTo(i);
+ EXPECT_FALSE(restartDecoder);
+ }
+
+ // Since we are below the threshold, we can reset the get index only.
+ // Nothing else should have changed.
+ restartDecoder = buffer.Reset();
+ EXPECT_FALSE(restartDecoder);
+ for (i = 0; i < 5; ++i) {
+ EXPECT_TRUE(buffer.Get(i, false) != nullptr);
+ }
+ EXPECT_EQ(size_t(0), buffer.PendingDecode());
+ EXPECT_EQ(size_t(0), buffer.PendingAdvance());
+ EXPECT_EQ(size_t(0), buffer.Displayed());
+}
+
+TEST_F(ImageAnimationFrameBuffer, StartAfterBeginning) {
+ const size_t kThreshold = 30;
+ const size_t kBatch = 2;
+ const size_t kStartFrame = 7;
+ AnimationFrameRetainedBuffer buffer(kThreshold, kBatch, kStartFrame);
+
+ EXPECT_EQ(kStartFrame, buffer.PendingAdvance());
+
+ // Add frames until it tells us to stop. It should be later than before,
+ // because it auto-advances until its displayed frame is kStartFrame.
+ AnimationFrameBuffer::InsertStatus status;
+ size_t i = 0;
+ do {
+ status = buffer.Insert(CreateEmptyFrame());
+ EXPECT_FALSE(buffer.SizeKnown());
+ EXPECT_FALSE(buffer.MayDiscard());
+
+ if (i <= kStartFrame) {
+ EXPECT_EQ(i, buffer.Displayed());
+ EXPECT_EQ(kStartFrame - i, buffer.PendingAdvance());
+ } else {
+ EXPECT_EQ(kStartFrame, buffer.Displayed());
+ EXPECT_EQ(size_t(0), buffer.PendingAdvance());
+ }
+
+ i++;
+ } while (status == AnimationFrameBuffer::InsertStatus::CONTINUE);
+
+ EXPECT_EQ(size_t(0), buffer.PendingDecode());
+ EXPECT_EQ(size_t(0), buffer.PendingAdvance());
+ EXPECT_EQ(size_t(10), buffer.Size());
+}
+
+TEST_F(ImageAnimationFrameBuffer, StartAfterBeginningAndReset) {
+ const size_t kThreshold = 30;
+ const size_t kBatch = 2;
+ const size_t kStartFrame = 7;
+ AnimationFrameRetainedBuffer buffer(kThreshold, kBatch, kStartFrame);
+
+ EXPECT_EQ(kStartFrame, buffer.PendingAdvance());
+
+ // Add frames until it tells us to stop. It should be later than before,
+ // because it auto-advances until its displayed frame is kStartFrame.
+ for (size_t i = 0; i < 5; ++i) {
+ AnimationFrameBuffer::InsertStatus status =
+ buffer.Insert(CreateEmptyFrame());
+ EXPECT_EQ(status, AnimationFrameBuffer::InsertStatus::CONTINUE);
+ EXPECT_FALSE(buffer.SizeKnown());
+ EXPECT_FALSE(buffer.MayDiscard());
+ EXPECT_EQ(i, buffer.Displayed());
+ EXPECT_EQ(kStartFrame - i, buffer.PendingAdvance());
+ }
+
+ // When we reset the animation, it goes back to the beginning. That means
+ // we can forget about what we were told to advance to at the start. While
+ // we have plenty of frames in our buffer, we still need one more because
+ // in the real scenario, the decoder thread is still running and it is easier
+ // to let it insert its last frame than to coordinate quitting earlier.
+ buffer.Reset();
+ EXPECT_EQ(size_t(0), buffer.Displayed());
+ EXPECT_EQ(size_t(1), buffer.PendingDecode());
+ EXPECT_EQ(size_t(0), buffer.PendingAdvance());
+ EXPECT_EQ(size_t(5), buffer.Size());
+}
+
+static void TestDiscardingQueueLoop(AnimationFrameDiscardingQueue& aQueue,
+ const imgFrame* aFirstFrame,
+ size_t aThreshold, size_t aBatch,
+ size_t aStartFrame) {
+ // We should be advanced right up to the last decoded frame.
+ EXPECT_TRUE(aQueue.MayDiscard());
+ EXPECT_FALSE(aQueue.SizeKnown());
+ EXPECT_EQ(aBatch, aQueue.Batch());
+ EXPECT_EQ(aThreshold, aQueue.PendingInsert());
+ EXPECT_EQ(aThreshold, aQueue.Size());
+ EXPECT_EQ(aFirstFrame, aQueue.FirstFrame());
+ EXPECT_EQ(size_t(1), aQueue.Display().size());
+ EXPECT_EQ(size_t(3), aQueue.PendingDecode());
+ VerifyDiscardingQueueContents(aQueue);
+
+ // Make sure frames get removed as we advance.
+ VerifyInsertAndAdvance(aQueue, 5,
+ AnimationFrameBuffer::InsertStatus::CONTINUE);
+ EXPECT_EQ(size_t(1), aQueue.Display().size());
+ VerifyInsertAndAdvance(aQueue, 6,
+ AnimationFrameBuffer::InsertStatus::CONTINUE);
+ EXPECT_EQ(size_t(1), aQueue.Display().size());
+
+ // We actually will yield if we are recycling instead of continuing because
+ // the pending calculation is slightly different. We will actually request one
+ // less frame than we have to recycle.
+ if (aQueue.IsRecycling()) {
+ VerifyInsertAndAdvance(aQueue, 7,
+ AnimationFrameBuffer::InsertStatus::YIELD);
+ } else {
+ VerifyInsertAndAdvance(aQueue, 7,
+ AnimationFrameBuffer::InsertStatus::CONTINUE);
+ }
+ EXPECT_EQ(size_t(1), aQueue.Display().size());
+
+ // We should get throttled if we insert too much.
+ VerifyInsert(aQueue, AnimationFrameBuffer::InsertStatus::CONTINUE);
+ EXPECT_EQ(size_t(2), aQueue.Display().size());
+ EXPECT_EQ(size_t(1), aQueue.PendingDecode());
+ VerifyInsert(aQueue, AnimationFrameBuffer::InsertStatus::YIELD);
+ EXPECT_EQ(size_t(3), aQueue.Display().size());
+ EXPECT_EQ(size_t(0), aQueue.PendingDecode());
+
+ // We should get restarted if we advance.
+ VerifyAdvance(aQueue, 8, true);
+ EXPECT_EQ(size_t(2), aQueue.PendingDecode());
+ VerifyAdvance(aQueue, 9, false);
+ EXPECT_EQ(size_t(2), aQueue.PendingDecode());
+
+ // We should continue decoding if we completed, since we are discarding.
+ VerifyMarkComplete(aQueue, true);
+ EXPECT_EQ(size_t(2), aQueue.PendingDecode());
+ EXPECT_EQ(size_t(10), aQueue.Size());
+ EXPECT_TRUE(aQueue.SizeKnown());
+ EXPECT_FALSE(aQueue.HasRedecodeError());
+
+ // Insert the first frames of the animation.
+ VerifyInsert(aQueue, AnimationFrameBuffer::InsertStatus::CONTINUE);
+ VerifyInsert(aQueue, AnimationFrameBuffer::InsertStatus::YIELD);
+ EXPECT_EQ(size_t(0), aQueue.PendingDecode());
+ EXPECT_EQ(size_t(10), aQueue.Size());
+
+ // Advance back at the beginning. The first frame should only match for
+ // display purposes.
+ VerifyAdvance(aQueue, 0, true);
+ EXPECT_EQ(size_t(2), aQueue.PendingDecode());
+ EXPECT_TRUE(aQueue.FirstFrame() != nullptr);
+ EXPECT_TRUE(aQueue.Get(0, false) != nullptr);
+ EXPECT_NE(aQueue.FirstFrame(), aQueue.Get(0, false));
+ EXPECT_EQ(aQueue.FirstFrame(), aQueue.Get(0, true));
+
+ // Reiterate one more time and make it loops back.
+ VerifyInsertAndAdvance(aQueue, 1,
+ AnimationFrameBuffer::InsertStatus::CONTINUE);
+ VerifyInsertAndAdvance(aQueue, 2, AnimationFrameBuffer::InsertStatus::YIELD);
+ VerifyInsertAndAdvance(aQueue, 3,
+ AnimationFrameBuffer::InsertStatus::CONTINUE);
+ VerifyInsertAndAdvance(aQueue, 4, AnimationFrameBuffer::InsertStatus::YIELD);
+ VerifyInsertAndAdvance(aQueue, 5,
+ AnimationFrameBuffer::InsertStatus::CONTINUE);
+ VerifyInsertAndAdvance(aQueue, 6, AnimationFrameBuffer::InsertStatus::YIELD);
+ VerifyInsertAndAdvance(aQueue, 7,
+ AnimationFrameBuffer::InsertStatus::CONTINUE);
+ VerifyInsertAndAdvance(aQueue, 8, AnimationFrameBuffer::InsertStatus::YIELD);
+
+ EXPECT_EQ(size_t(10), aQueue.PendingInsert());
+ VerifyMarkComplete(aQueue, true);
+ EXPECT_EQ(size_t(0), aQueue.PendingInsert());
+
+ VerifyInsertAndAdvance(aQueue, 9,
+ AnimationFrameBuffer::InsertStatus::CONTINUE);
+ VerifyInsertAndAdvance(aQueue, 0, AnimationFrameBuffer::InsertStatus::YIELD);
+ VerifyInsertAndAdvance(aQueue, 1,
+ AnimationFrameBuffer::InsertStatus::CONTINUE);
+}
+
+TEST_F(ImageAnimationFrameBuffer, DiscardingLoop) {
+ const size_t kThreshold = 5;
+ const size_t kBatch = 2;
+ const size_t kStartFrame = 0;
+ AnimationFrameRetainedBuffer retained(kThreshold, kBatch, kStartFrame);
+ PrepareForDiscardingQueue(retained);
+ const imgFrame* firstFrame = retained.Frames()[0].get();
+ AnimationFrameDiscardingQueue buffer(std::move(retained));
+ TestDiscardingQueueLoop(buffer, firstFrame, kThreshold, kBatch, kStartFrame);
+}
+
+TEST_F(ImageAnimationFrameBuffer, RecyclingLoop) {
+ const size_t kThreshold = 5;
+ const size_t kBatch = 2;
+ const size_t kStartFrame = 0;
+ AnimationFrameRetainedBuffer retained(kThreshold, kBatch, kStartFrame);
+ PrepareForDiscardingQueue(retained);
+ const imgFrame* firstFrame = retained.Frames()[0].get();
+ AnimationFrameRecyclingQueue buffer(std::move(retained));
+
+ // We should not start with any recycled frames.
+ ASSERT_TRUE(buffer.Recycle().empty());
+
+ TestDiscardingQueueLoop(buffer, firstFrame, kThreshold, kBatch, kStartFrame);
+
+ // All the frames we inserted should have been recycleable.
+ ASSERT_FALSE(buffer.Recycle().empty());
+ while (!buffer.Recycle().empty()) {
+ gfx::IntRect expectedRect(0, 0, 1, 1);
+ RefPtr<imgFrame> expectedFrame = buffer.Recycle().front().mFrame;
+ EXPECT_FALSE(expectedRect.IsEmpty());
+ EXPECT_TRUE(expectedFrame.get() != nullptr);
+
+ gfx::IntRect gotRect;
+ RawAccessFrameRef gotFrame = buffer.RecycleFrame(gotRect);
+ EXPECT_EQ(expectedFrame.get(), gotFrame.get());
+ EXPECT_EQ(expectedRect, gotRect);
+ EXPECT_TRUE(ReinitForRecycle(gotFrame));
+ }
+
+ // Trying to pull a recycled frame when we have nothing should be safe too.
+ gfx::IntRect gotRect;
+ RawAccessFrameRef gotFrame = buffer.RecycleFrame(gotRect);
+ EXPECT_TRUE(gotFrame.get() == nullptr);
+ EXPECT_FALSE(ReinitForRecycle(gotFrame));
+}
+
+static void TestDiscardingQueueReset(AnimationFrameDiscardingQueue& aQueue,
+ const imgFrame* aFirstFrame,
+ size_t aThreshold, size_t aBatch,
+ size_t aStartFrame) {
+ // We should be advanced right up to the last decoded frame.
+ EXPECT_TRUE(aQueue.MayDiscard());
+ EXPECT_FALSE(aQueue.SizeKnown());
+ EXPECT_EQ(aBatch, aQueue.Batch());
+ EXPECT_EQ(aThreshold, aQueue.PendingInsert());
+ EXPECT_EQ(aThreshold, aQueue.Size());
+ EXPECT_EQ(aFirstFrame, aQueue.FirstFrame());
+ EXPECT_EQ(size_t(1), aQueue.Display().size());
+ EXPECT_EQ(size_t(4), aQueue.PendingDecode());
+ VerifyDiscardingQueueContents(aQueue);
+
+ // Reset should clear everything except the first frame.
+ VerifyReset(aQueue, false, aFirstFrame);
+}
+
+TEST_F(ImageAnimationFrameBuffer, DiscardingReset) {
+ const size_t kThreshold = 8;
+ const size_t kBatch = 3;
+ const size_t kStartFrame = 0;
+ AnimationFrameRetainedBuffer retained(kThreshold, kBatch, kStartFrame);
+ PrepareForDiscardingQueue(retained);
+ const imgFrame* firstFrame = retained.Frames()[0].get();
+ AnimationFrameDiscardingQueue buffer(std::move(retained));
+ TestDiscardingQueueReset(buffer, firstFrame, kThreshold, kBatch, kStartFrame);
+}
+
+TEST_F(ImageAnimationFrameBuffer, ResetBeforeDiscardingThreshold) {
+ const size_t kThreshold = 3;
+ const size_t kBatch = 1;
+ const size_t kStartFrame = 0;
+
+ // Get the starting buffer to just before the point where we need to switch
+ // to a discarding buffer, reset the animation so advancing points at the
+ // first frame, and insert the last frame to cross the threshold.
+ AnimationFrameRetainedBuffer retained(kThreshold, kBatch, kStartFrame);
+ VerifyInsert(retained, AnimationFrameBuffer::InsertStatus::CONTINUE);
+ VerifyInsertAndAdvance(retained, 1,
+ AnimationFrameBuffer::InsertStatus::YIELD);
+ bool restartDecoder = retained.Reset();
+ EXPECT_FALSE(restartDecoder);
+ VerifyInsert(retained, AnimationFrameBuffer::InsertStatus::DISCARD_YIELD);
+
+ const imgFrame* firstFrame = retained.Frames()[0].get();
+ EXPECT_TRUE(firstFrame != nullptr);
+ AnimationFrameDiscardingQueue buffer(std::move(retained));
+ const imgFrame* displayFirstFrame = buffer.Get(0, true);
+ const imgFrame* advanceFirstFrame = buffer.Get(0, false);
+ EXPECT_EQ(firstFrame, displayFirstFrame);
+ EXPECT_EQ(firstFrame, advanceFirstFrame);
+}
+
+TEST_F(ImageAnimationFrameBuffer, DiscardingTooFewFrames) {
+ const size_t kThreshold = 3;
+ const size_t kBatch = 1;
+ const size_t kStartFrame = 0;
+
+ // First get us to a discarding buffer state.
+ AnimationFrameRetainedBuffer retained(kThreshold, kBatch, kStartFrame);
+ VerifyInsert(retained, AnimationFrameBuffer::InsertStatus::CONTINUE);
+ VerifyInsertAndAdvance(retained, 1,
+ AnimationFrameBuffer::InsertStatus::YIELD);
+ VerifyInsert(retained, AnimationFrameBuffer::InsertStatus::DISCARD_YIELD);
+
+ // Insert one more frame.
+ AnimationFrameDiscardingQueue buffer(std::move(retained));
+ VerifyAdvance(buffer, 2, true);
+ VerifyInsert(buffer, AnimationFrameBuffer::InsertStatus::YIELD);
+
+ // Mark it as complete.
+ bool restartDecoder = buffer.MarkComplete(gfx::IntRect(0, 0, 1, 1));
+ EXPECT_FALSE(restartDecoder);
+ EXPECT_FALSE(buffer.HasRedecodeError());
+
+ // Insert one fewer frame than before.
+ VerifyAdvance(buffer, 3, true);
+ VerifyInsertAndAdvance(buffer, 0, AnimationFrameBuffer::InsertStatus::YIELD);
+ VerifyInsertAndAdvance(buffer, 1, AnimationFrameBuffer::InsertStatus::YIELD);
+ VerifyInsertAndAdvance(buffer, 2, AnimationFrameBuffer::InsertStatus::YIELD);
+
+ // When we mark it as complete, it should fail due to too few frames.
+ restartDecoder = buffer.MarkComplete(gfx::IntRect(0, 0, 1, 1));
+ EXPECT_TRUE(buffer.HasRedecodeError());
+ EXPECT_EQ(size_t(0), buffer.PendingDecode());
+ EXPECT_EQ(size_t(4), buffer.Size());
+}
+
+TEST_F(ImageAnimationFrameBuffer, DiscardingTooManyFrames) {
+ const size_t kThreshold = 3;
+ const size_t kBatch = 1;
+ const size_t kStartFrame = 0;
+
+ // First get us to a discarding buffer state.
+ AnimationFrameRetainedBuffer retained(kThreshold, kBatch, kStartFrame);
+ VerifyInsert(retained, AnimationFrameBuffer::InsertStatus::CONTINUE);
+ VerifyInsertAndAdvance(retained, 1,
+ AnimationFrameBuffer::InsertStatus::YIELD);
+ VerifyInsert(retained, AnimationFrameBuffer::InsertStatus::DISCARD_YIELD);
+
+ // Insert one more frame.
+ AnimationFrameDiscardingQueue buffer(std::move(retained));
+ VerifyAdvance(buffer, 2, true);
+ VerifyInsert(buffer, AnimationFrameBuffer::InsertStatus::YIELD);
+
+ // Mark it as complete.
+ bool restartDecoder = buffer.MarkComplete(gfx::IntRect(0, 0, 1, 1));
+ EXPECT_FALSE(restartDecoder);
+ EXPECT_FALSE(buffer.HasRedecodeError());
+
+ // Advance and insert to get us back to the end on the redecode.
+ VerifyAdvance(buffer, 3, true);
+ VerifyInsertAndAdvance(buffer, 0, AnimationFrameBuffer::InsertStatus::YIELD);
+ VerifyInsertAndAdvance(buffer, 1, AnimationFrameBuffer::InsertStatus::YIELD);
+ VerifyInsertAndAdvance(buffer, 2, AnimationFrameBuffer::InsertStatus::YIELD);
+ VerifyInsertAndAdvance(buffer, 3, AnimationFrameBuffer::InsertStatus::YIELD);
+
+ // Attempt to insert a 5th frame, it should fail.
+ RefPtr<imgFrame> frame = CreateEmptyFrame();
+ AnimationFrameBuffer::InsertStatus status = buffer.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status);
+ EXPECT_TRUE(buffer.HasRedecodeError());
+ EXPECT_EQ(size_t(0), buffer.PendingDecode());
+ EXPECT_EQ(size_t(4), buffer.Size());
+}
+
+TEST_F(ImageAnimationFrameBuffer, RecyclingReset) {
+ const size_t kThreshold = 8;
+ const size_t kBatch = 3;
+ const size_t kStartFrame = 0;
+ AnimationFrameRetainedBuffer retained(kThreshold, kBatch, kStartFrame);
+ PrepareForDiscardingQueue(retained);
+ const imgFrame* firstFrame = retained.Frames()[0].get();
+ AnimationFrameRecyclingQueue buffer(std::move(retained));
+ TestDiscardingQueueReset(buffer, firstFrame, kThreshold, kBatch, kStartFrame);
+}
+
+TEST_F(ImageAnimationFrameBuffer, RecyclingResetBeforeComplete) {
+ const size_t kThreshold = 3;
+ const size_t kBatch = 1;
+ const size_t kStartFrame = 0;
+ const gfx::IntSize kImageSize(100, 100);
+ const gfx::IntRect kImageRect(gfx::IntPoint(0, 0), kImageSize);
+ AnimationFrameRetainedBuffer retained(kThreshold, kBatch, kStartFrame);
+
+ // Get the starting buffer to just before the point where we need to switch
+ // to a discarding buffer, reset the animation so advancing points at the
+ // first frame, and insert the last frame to cross the threshold.
+ RefPtr<imgFrame> frame;
+ frame = CreateEmptyFrame(kImageSize, kImageRect, false);
+ AnimationFrameBuffer::InsertStatus status = retained.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::CONTINUE, status);
+
+ frame = CreateEmptyFrame(
+ kImageSize, gfx::IntRect(gfx::IntPoint(10, 10), gfx::IntSize(1, 1)),
+ false);
+ status = retained.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status);
+
+ VerifyAdvance(retained, 1, true);
+
+ frame = CreateEmptyFrame(
+ kImageSize, gfx::IntRect(gfx::IntPoint(20, 10), gfx::IntSize(1, 1)),
+ false);
+ status = retained.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::DISCARD_YIELD, status);
+
+ AnimationFrameRecyclingQueue buffer(std::move(retained));
+ bool restartDecoding = buffer.Reset();
+ EXPECT_TRUE(restartDecoding);
+
+ // None of the buffers were recyclable.
+ EXPECT_FALSE(buffer.Recycle().empty());
+ while (!buffer.Recycle().empty()) {
+ gfx::IntRect recycleRect;
+ RawAccessFrameRef frameRef = buffer.RecycleFrame(recycleRect);
+ EXPECT_TRUE(frameRef);
+ EXPECT_FALSE(ReinitForRecycle(frameRef));
+ }
+
+ // Reinsert the first two frames as recyclable and reset again.
+ frame = CreateEmptyFrame(kImageSize, kImageRect, true);
+ status = buffer.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::CONTINUE, status);
+
+ frame = CreateEmptyFrame(
+ kImageSize, gfx::IntRect(gfx::IntPoint(10, 10), gfx::IntSize(1, 1)),
+ true);
+ status = buffer.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status);
+
+ restartDecoding = buffer.Reset();
+ EXPECT_TRUE(restartDecoding);
+
+ // Now both buffers should have been saved and the dirty rect replaced with
+ // the full image rect since we don't know the first frame refresh area yet.
+ EXPECT_EQ(size_t(2), buffer.Recycle().size());
+ for (const auto& entry : buffer.Recycle()) {
+ EXPECT_EQ(kImageRect, entry.mDirtyRect);
+ }
+}
+
+TEST_F(ImageAnimationFrameBuffer, RecyclingRect) {
+ const size_t kThreshold = 5;
+ const size_t kBatch = 2;
+ const size_t kStartFrame = 0;
+ const gfx::IntSize kImageSize(100, 100);
+ const gfx::IntRect kImageRect(gfx::IntPoint(0, 0), kImageSize);
+ AnimationFrameRetainedBuffer retained(kThreshold, kBatch, kStartFrame);
+
+ // Let's get to the recycling state while marking all of the frames as not
+ // recyclable, just like AnimationFrameBuffer / the decoders would do.
+ RefPtr<imgFrame> frame;
+ frame = CreateEmptyFrame(kImageSize, kImageRect, false);
+ AnimationFrameBuffer::InsertStatus status = retained.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::CONTINUE, status);
+
+ frame = CreateEmptyFrame(kImageSize, kImageRect, false);
+ status = retained.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::CONTINUE, status);
+
+ frame = CreateEmptyFrame(kImageSize, kImageRect, false);
+ status = retained.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::CONTINUE, status);
+
+ frame = CreateEmptyFrame(kImageSize, kImageRect, false);
+ status = retained.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status);
+
+ VerifyAdvance(retained, 1, false);
+ VerifyAdvance(retained, 2, true);
+ VerifyAdvance(retained, 3, false);
+
+ frame = CreateEmptyFrame(kImageSize, kImageRect, false);
+ status = retained.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::DISCARD_CONTINUE, status);
+
+ AnimationFrameRecyclingQueue buffer(std::move(retained));
+
+ // The first frame is now the candidate for recycling. Since it was marked as
+ // not recyclable, we should get nothing.
+ VerifyAdvance(buffer, 4, false);
+
+ gfx::IntRect recycleRect;
+ EXPECT_FALSE(buffer.Recycle().empty());
+ RawAccessFrameRef frameRef = buffer.RecycleFrame(recycleRect);
+ EXPECT_TRUE(frameRef);
+ EXPECT_FALSE(ReinitForRecycle(frameRef));
+ EXPECT_TRUE(buffer.Recycle().empty());
+
+ // Insert a recyclable partial frame. Its dirty rect shouldn't matter since
+ // the previous frame was not recyclable.
+ frame = CreateEmptyFrame(kImageSize, gfx::IntRect(0, 0, 25, 25));
+ status = buffer.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status);
+
+ VerifyAdvance(buffer, 5, true);
+ EXPECT_FALSE(buffer.Recycle().empty());
+ frameRef = buffer.RecycleFrame(recycleRect);
+ EXPECT_TRUE(frameRef);
+ EXPECT_FALSE(ReinitForRecycle(frameRef));
+ EXPECT_TRUE(buffer.Recycle().empty());
+
+ // Insert a recyclable partial frame. Its dirty rect should match the recycle
+ // rect since it is the only frame in the buffer.
+ frame = CreateEmptyFrame(kImageSize, gfx::IntRect(25, 0, 50, 50));
+ status = buffer.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status);
+
+ VerifyAdvance(buffer, 6, true);
+ EXPECT_FALSE(buffer.Recycle().empty());
+ frameRef = buffer.RecycleFrame(recycleRect);
+ EXPECT_TRUE(frameRef);
+ EXPECT_TRUE(ReinitForRecycle(frameRef));
+ EXPECT_EQ(gfx::IntRect(25, 0, 50, 50), recycleRect);
+ EXPECT_TRUE(buffer.Recycle().empty());
+
+ // Insert the last frame and mark us as complete. The next recycled frame is
+ // producing the first frame again, so we should use the first frame refresh
+ // area instead of its dirty rect.
+ frame = CreateEmptyFrame(kImageSize, gfx::IntRect(10, 10, 60, 10));
+ status = buffer.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status);
+
+ bool continueDecoding = buffer.MarkComplete(gfx::IntRect(0, 0, 75, 50));
+ EXPECT_FALSE(continueDecoding);
+
+ VerifyAdvance(buffer, 7, true);
+ EXPECT_FALSE(buffer.Recycle().empty());
+ frameRef = buffer.RecycleFrame(recycleRect);
+ EXPECT_TRUE(frameRef);
+ EXPECT_TRUE(ReinitForRecycle(frameRef));
+ EXPECT_EQ(gfx::IntRect(0, 0, 75, 50), recycleRect);
+ EXPECT_TRUE(buffer.Recycle().empty());
+
+ // Now let's reinsert the first frame. The recycle rect should still be the
+ // first frame refresh area instead of the dirty rect of the first frame (e.g.
+ // the full frame).
+ frame = CreateEmptyFrame(kImageSize, kImageRect, false);
+ status = buffer.Insert(std::move(frame));
+ EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status);
+
+ VerifyAdvance(buffer, 0, true);
+ EXPECT_FALSE(buffer.Recycle().empty());
+ frameRef = buffer.RecycleFrame(recycleRect);
+ EXPECT_TRUE(frameRef);
+ EXPECT_TRUE(ReinitForRecycle(frameRef));
+ EXPECT_EQ(gfx::IntRect(0, 0, 75, 50), recycleRect);
+ EXPECT_TRUE(buffer.Recycle().empty());
+}
diff --git a/image/test/gtest/TestBlendAnimationFilter.cpp b/image/test/gtest/TestBlendAnimationFilter.cpp
new file mode 100644
index 0000000000..7291fbc3f6
--- /dev/null
+++ b/image/test/gtest/TestBlendAnimationFilter.cpp
@@ -0,0 +1,450 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "mozilla/gfx/2D.h"
+#include "skia/include/core/SkColorPriv.h" // for SkPMSrcOver
+#include "Common.h"
+#include "Decoder.h"
+#include "DecoderFactory.h"
+#include "SourceBuffer.h"
+#include "SurfaceFilters.h"
+#include "SurfacePipe.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+static already_AddRefed<image::Decoder> CreateTrivialBlendingDecoder() {
+ DecoderType decoderType = DecoderFactory::GetDecoderType("image/gif");
+ DecoderFlags decoderFlags = DefaultDecoderFlags();
+ SurfaceFlags surfaceFlags = DefaultSurfaceFlags();
+ auto sourceBuffer = MakeNotNull<RefPtr<SourceBuffer>>();
+ return DecoderFactory::CreateAnonymousDecoder(
+ decoderType, sourceBuffer, Nothing(), decoderFlags, surfaceFlags);
+}
+
+template <typename Func>
+RawAccessFrameRef WithBlendAnimationFilter(image::Decoder* aDecoder,
+ const AnimationParams& aAnimParams,
+ const IntSize& aOutputSize,
+ Func aFunc) {
+ DecoderTestHelper decoderHelper(aDecoder);
+
+ if (!aDecoder->HasAnimation()) {
+ decoderHelper.PostIsAnimated(aAnimParams.mTimeout);
+ }
+
+ BlendAnimationConfig blendAnim{aDecoder};
+ SurfaceConfig surfaceSink{aDecoder, aOutputSize, SurfaceFormat::OS_RGBA,
+ false, Some(aAnimParams)};
+
+ auto func = [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ aFunc(aDecoder, aFilter);
+ };
+
+ WithFilterPipeline(aDecoder, func, false, blendAnim, surfaceSink);
+
+ RawAccessFrameRef current = aDecoder->GetCurrentFrameRef();
+ if (current) {
+ decoderHelper.PostFrameStop(Opacity::SOME_TRANSPARENCY);
+ }
+
+ return current;
+}
+
+void AssertConfiguringBlendAnimationFilterFails(const IntRect& aFrameRect,
+ const IntSize& aOutputSize) {
+ RefPtr<image::Decoder> decoder = CreateTrivialBlendingDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ AnimationParams animParams{aFrameRect, FrameTimeout::FromRawMilliseconds(0),
+ 0, BlendMethod::SOURCE, DisposalMethod::KEEP};
+ BlendAnimationConfig blendAnim{decoder};
+ SurfaceConfig surfaceSink{decoder, aOutputSize, SurfaceFormat::OS_RGBA, false,
+ Some(animParams)};
+ AssertConfiguringPipelineFails(decoder, blendAnim, surfaceSink);
+}
+
+TEST(ImageBlendAnimationFilter, BlendFailsForNegativeFrameRect)
+{
+ // A negative frame rect size is disallowed.
+ AssertConfiguringBlendAnimationFilterFails(
+ IntRect(IntPoint(0, 0), IntSize(-1, -1)), IntSize(100, 100));
+}
+
+TEST(ImageBlendAnimationFilter, WriteFullFirstFrame)
+{
+ RefPtr<image::Decoder> decoder = CreateTrivialBlendingDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ AnimationParams params{
+ IntRect(0, 0, 100, 100), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 0, BlendMethod::SOURCE, DisposalMethod::KEEP};
+ RawAccessFrameRef frame0 = WithBlendAnimationFilter(
+ decoder, params, IntSize(100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter, Some(IntRect(0, 0, 100, 100)));
+ });
+ EXPECT_EQ(IntRect(0, 0, 100, 100), frame0->GetDirtyRect());
+}
+
+TEST(ImageBlendAnimationFilter, WritePartialFirstFrame)
+{
+ RefPtr<image::Decoder> decoder = CreateTrivialBlendingDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ AnimationParams params{
+ IntRect(25, 50, 50, 25), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 0, BlendMethod::SOURCE, DisposalMethod::KEEP};
+ RawAccessFrameRef frame0 = WithBlendAnimationFilter(
+ decoder, params, IntSize(100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter, Some(IntRect(0, 0, 100, 100)),
+ Nothing(), Some(IntRect(25, 50, 50, 25)),
+ Some(IntRect(25, 50, 50, 25)));
+ });
+ EXPECT_EQ(IntRect(0, 0, 100, 100), frame0->GetDirtyRect());
+}
+
+static void TestWithBlendAnimationFilterClear(BlendMethod aBlendMethod) {
+ RefPtr<image::Decoder> decoder = CreateTrivialBlendingDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ AnimationParams params0{
+ IntRect(0, 0, 100, 100), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 0, BlendMethod::SOURCE, DisposalMethod::KEEP};
+ RawAccessFrameRef frame0 = WithBlendAnimationFilter(
+ decoder, params0, IntSize(100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(BGRAColor::Green().AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 0, 100, 100), frame0->GetDirtyRect());
+
+ AnimationParams params1{
+ IntRect(0, 40, 100, 20), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 1, BlendMethod::SOURCE, DisposalMethod::CLEAR};
+ RawAccessFrameRef frame1 = WithBlendAnimationFilter(
+ decoder, params1, IntSize(100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(BGRAColor::Red().AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 40, 100, 20), frame1->GetDirtyRect());
+
+ ASSERT_TRUE(frame1.get() != nullptr);
+
+ RefPtr<SourceSurface> surface = frame1->GetSourceSurface();
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 40, BGRAColor::Green()));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 40, 20, BGRAColor::Red()));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 60, 40, BGRAColor::Green()));
+
+ AnimationParams params2{
+ IntRect(0, 50, 100, 20), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 2, aBlendMethod, DisposalMethod::KEEP};
+ RawAccessFrameRef frame2 = WithBlendAnimationFilter(
+ decoder, params2, IntSize(100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(BGRAColor::Blue().AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+
+ ASSERT_TRUE(frame2.get() != nullptr);
+
+ surface = frame2->GetSourceSurface();
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 40, BGRAColor::Green()));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 40, 10, BGRAColor::Transparent()));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 50, 20, BGRAColor::Blue()));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 70, 30, BGRAColor::Green()));
+}
+
+TEST(ImageBlendAnimationFilter, ClearWithOver)
+{ TestWithBlendAnimationFilterClear(BlendMethod::OVER); }
+
+TEST(ImageBlendAnimationFilter, ClearWithSource)
+{ TestWithBlendAnimationFilterClear(BlendMethod::SOURCE); }
+
+TEST(ImageBlendAnimationFilter, KeepWithSource)
+{
+ RefPtr<image::Decoder> decoder = CreateTrivialBlendingDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ AnimationParams params0{
+ IntRect(0, 0, 100, 100), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 0, BlendMethod::SOURCE, DisposalMethod::KEEP};
+ RawAccessFrameRef frame0 = WithBlendAnimationFilter(
+ decoder, params0, IntSize(100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(BGRAColor::Green().AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 0, 100, 100), frame0->GetDirtyRect());
+
+ AnimationParams params1{
+ IntRect(0, 40, 100, 20), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 1, BlendMethod::SOURCE, DisposalMethod::KEEP};
+ RawAccessFrameRef frame1 = WithBlendAnimationFilter(
+ decoder, params1, IntSize(100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(BGRAColor::Red().AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 40, 100, 20), frame1->GetDirtyRect());
+
+ ASSERT_TRUE(frame1.get() != nullptr);
+
+ RefPtr<SourceSurface> surface = frame1->GetSourceSurface();
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 40, BGRAColor::Green()));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 40, 20, BGRAColor::Red()));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 60, 40, BGRAColor::Green()));
+}
+
+TEST(ImageBlendAnimationFilter, KeepWithOver)
+{
+ RefPtr<image::Decoder> decoder = CreateTrivialBlendingDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ AnimationParams params0{
+ IntRect(0, 0, 100, 100), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 0, BlendMethod::SOURCE, DisposalMethod::KEEP};
+ BGRAColor frameColor0(0, 0xFF, 0, 0x40);
+ RawAccessFrameRef frame0 = WithBlendAnimationFilter(
+ decoder, params0, IntSize(100, 100),
+ [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(frameColor0.AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 0, 100, 100), frame0->GetDirtyRect());
+
+ AnimationParams params1{
+ IntRect(0, 40, 100, 20), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 1, BlendMethod::OVER, DisposalMethod::KEEP};
+ BGRAColor frameColor1(0, 0, 0xFF, 0x80);
+ RawAccessFrameRef frame1 = WithBlendAnimationFilter(
+ decoder, params1, IntSize(100, 100),
+ [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(frameColor1.AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 40, 100, 20), frame1->GetDirtyRect());
+
+ ASSERT_TRUE(frame1.get() != nullptr);
+
+ BGRAColor blendedColor(0, 0x20, 0x80, 0xA0, true); // already premultiplied
+ EXPECT_EQ(SkPMSrcOver(frameColor1.AsPixel(), frameColor0.AsPixel()),
+ blendedColor.AsPixel());
+
+ RefPtr<SourceSurface> surface = frame1->GetSourceSurface();
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 40, frameColor0));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 40, 20, blendedColor));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 60, 40, frameColor0));
+}
+
+TEST(ImageBlendAnimationFilter, RestorePreviousWithOver)
+{
+ RefPtr<image::Decoder> decoder = CreateTrivialBlendingDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ AnimationParams params0{
+ IntRect(0, 0, 100, 100), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 0, BlendMethod::SOURCE, DisposalMethod::KEEP};
+ BGRAColor frameColor0(0, 0xFF, 0, 0x40);
+ RawAccessFrameRef frame0 = WithBlendAnimationFilter(
+ decoder, params0, IntSize(100, 100),
+ [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(frameColor0.AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 0, 100, 100), frame0->GetDirtyRect());
+
+ AnimationParams params1{
+ IntRect(0, 10, 100, 80), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 1, BlendMethod::SOURCE, DisposalMethod::RESTORE_PREVIOUS};
+ BGRAColor frameColor1 = BGRAColor::Green();
+ RawAccessFrameRef frame1 = WithBlendAnimationFilter(
+ decoder, params1, IntSize(100, 100),
+ [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(frameColor1.AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 10, 100, 80), frame1->GetDirtyRect());
+
+ AnimationParams params2{
+ IntRect(0, 40, 100, 20), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 2, BlendMethod::OVER, DisposalMethod::KEEP};
+ BGRAColor frameColor2(0, 0, 0xFF, 0x80);
+ RawAccessFrameRef frame2 = WithBlendAnimationFilter(
+ decoder, params2, IntSize(100, 100),
+ [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(frameColor2.AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 10, 100, 80), frame2->GetDirtyRect());
+
+ ASSERT_TRUE(frame2.get() != nullptr);
+
+ BGRAColor blendedColor(0, 0x20, 0x80, 0xA0, true); // already premultiplied
+ EXPECT_EQ(SkPMSrcOver(frameColor2.AsPixel(), frameColor0.AsPixel()),
+ blendedColor.AsPixel());
+
+ RefPtr<SourceSurface> surface = frame2->GetSourceSurface();
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 40, frameColor0));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 40, 20, blendedColor));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 60, 40, frameColor0));
+}
+
+TEST(ImageBlendAnimationFilter, RestorePreviousWithSource)
+{
+ RefPtr<image::Decoder> decoder = CreateTrivialBlendingDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ AnimationParams params0{
+ IntRect(0, 0, 100, 100), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 0, BlendMethod::SOURCE, DisposalMethod::KEEP};
+ BGRAColor frameColor0(0, 0xFF, 0, 0x40);
+ RawAccessFrameRef frame0 = WithBlendAnimationFilter(
+ decoder, params0, IntSize(100, 100),
+ [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(frameColor0.AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 0, 100, 100), frame0->GetDirtyRect());
+
+ AnimationParams params1{
+ IntRect(0, 10, 100, 80), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 1, BlendMethod::SOURCE, DisposalMethod::RESTORE_PREVIOUS};
+ BGRAColor frameColor1 = BGRAColor::Green();
+ RawAccessFrameRef frame1 = WithBlendAnimationFilter(
+ decoder, params1, IntSize(100, 100),
+ [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(frameColor1.AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 10, 100, 80), frame1->GetDirtyRect());
+
+ AnimationParams params2{
+ IntRect(0, 40, 100, 20), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 2, BlendMethod::SOURCE, DisposalMethod::KEEP};
+ BGRAColor frameColor2(0, 0, 0xFF, 0x80);
+ RawAccessFrameRef frame2 = WithBlendAnimationFilter(
+ decoder, params2, IntSize(100, 100),
+ [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(frameColor2.AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 10, 100, 80), frame2->GetDirtyRect());
+
+ ASSERT_TRUE(frame2.get() != nullptr);
+
+ RefPtr<SourceSurface> surface = frame2->GetSourceSurface();
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 40, frameColor0));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 40, 20, frameColor2));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 60, 40, frameColor0));
+}
+
+TEST(ImageBlendAnimationFilter, RestorePreviousClearWithSource)
+{
+ RefPtr<image::Decoder> decoder = CreateTrivialBlendingDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ AnimationParams params0{
+ IntRect(0, 0, 100, 100), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 0, BlendMethod::SOURCE, DisposalMethod::KEEP};
+ BGRAColor frameColor0 = BGRAColor::Red();
+ RawAccessFrameRef frame0 = WithBlendAnimationFilter(
+ decoder, params0, IntSize(100, 100),
+ [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(frameColor0.AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 0, 100, 100), frame0->GetDirtyRect());
+
+ AnimationParams params1{
+ IntRect(0, 0, 100, 20), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 1, BlendMethod::SOURCE, DisposalMethod::CLEAR};
+ BGRAColor frameColor1 = BGRAColor::Blue();
+ RawAccessFrameRef frame1 = WithBlendAnimationFilter(
+ decoder, params1, IntSize(100, 100),
+ [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(frameColor1.AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 0, 100, 20), frame1->GetDirtyRect());
+
+ AnimationParams params2{
+ IntRect(0, 10, 100, 80), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 2, BlendMethod::SOURCE, DisposalMethod::RESTORE_PREVIOUS};
+ BGRAColor frameColor2 = BGRAColor::Green();
+ RawAccessFrameRef frame2 = WithBlendAnimationFilter(
+ decoder, params2, IntSize(100, 100),
+ [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(frameColor2.AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 0, 100, 90), frame2->GetDirtyRect());
+
+ AnimationParams params3{
+ IntRect(0, 40, 100, 20), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 3, BlendMethod::SOURCE, DisposalMethod::KEEP};
+ BGRAColor frameColor3 = BGRAColor::Blue();
+ RawAccessFrameRef frame3 = WithBlendAnimationFilter(
+ decoder, params3, IntSize(100, 100),
+ [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(frameColor3.AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 0, 100, 90), frame3->GetDirtyRect());
+
+ ASSERT_TRUE(frame3.get() != nullptr);
+
+ RefPtr<SourceSurface> surface = frame3->GetSourceSurface();
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 20, BGRAColor::Transparent()));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 20, 20, frameColor0));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 40, 20, frameColor3));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 60, 40, frameColor0));
+}
+
+TEST(ImageBlendAnimationFilter, PartialOverlapFrameRect)
+{
+ RefPtr<image::Decoder> decoder = CreateTrivialBlendingDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ AnimationParams params0{
+ IntRect(-10, -20, 110, 100), FrameTimeout::FromRawMilliseconds(0),
+ /* aFrameNum */ 0, BlendMethod::SOURCE, DisposalMethod::KEEP};
+ BGRAColor frameColor0 = BGRAColor::Red();
+ RawAccessFrameRef frame0 = WithBlendAnimationFilter(
+ decoder, params0, IntSize(100, 100),
+ [&](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ auto result = aFilter->WritePixels<uint32_t>(
+ [&] { return AsVariant(frameColor0.AsPixel()); });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ });
+ EXPECT_EQ(IntRect(0, 0, 100, 100), frame0->GetDirtyRect());
+
+ RefPtr<SourceSurface> surface = frame0->GetSourceSurface();
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 80, frameColor0));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 80, 20, BGRAColor::Transparent()));
+}
diff --git a/image/test/gtest/TestCopyOnWrite.cpp b/image/test/gtest/TestCopyOnWrite.cpp
new file mode 100644
index 0000000000..d5ad3e4f6b
--- /dev/null
+++ b/image/test/gtest/TestCopyOnWrite.cpp
@@ -0,0 +1,237 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "CopyOnWrite.h"
+
+using namespace mozilla;
+using namespace mozilla::image;
+
+struct ValueStats {
+ int32_t mCopies = 0;
+ int32_t mFrees = 0;
+ int32_t mCalls = 0;
+ int32_t mConstCalls = 0;
+ int32_t mSerial = 0;
+};
+
+struct Value {
+ NS_INLINE_DECL_REFCOUNTING(Value)
+
+ explicit Value(ValueStats& aStats)
+ : mStats(aStats), mSerial(mStats.mSerial++) {}
+
+ Value(const Value& aOther)
+ : mStats(aOther.mStats), mSerial(mStats.mSerial++) {
+ mStats.mCopies++;
+ }
+
+ void Go() { mStats.mCalls++; }
+ void Go() const { mStats.mConstCalls++; }
+
+ int32_t Serial() const { return mSerial; }
+
+ protected:
+ ~Value() { mStats.mFrees++; }
+
+ private:
+ ValueStats& mStats;
+ int32_t mSerial;
+};
+
+TEST(ImageCopyOnWrite, Read)
+{
+ ValueStats stats;
+
+ {
+ CopyOnWrite<Value> cow(new Value(stats));
+
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_TRUE(cow.CanRead());
+
+ cow.Read([&](const Value* aValue) {
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_EQ(0, aValue->Serial());
+ EXPECT_TRUE(cow.CanRead());
+ EXPECT_TRUE(cow.CanWrite());
+
+ aValue->Go();
+
+ EXPECT_EQ(0, stats.mCalls);
+ EXPECT_EQ(1, stats.mConstCalls);
+ });
+
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_EQ(0, stats.mCalls);
+ EXPECT_EQ(1, stats.mConstCalls);
+ }
+
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(1, stats.mFrees);
+}
+
+TEST(ImageCopyOnWrite, RecursiveRead)
+{
+ ValueStats stats;
+
+ {
+ CopyOnWrite<Value> cow(new Value(stats));
+
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_TRUE(cow.CanRead());
+
+ cow.Read([&](const Value* aValue) {
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_EQ(0, aValue->Serial());
+ EXPECT_TRUE(cow.CanRead());
+ EXPECT_TRUE(cow.CanWrite());
+
+ // Make sure that Read() inside a Read() succeeds.
+ cow.Read(
+ [&](const Value* aValue) {
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_EQ(0, aValue->Serial());
+ EXPECT_TRUE(cow.CanRead());
+ EXPECT_TRUE(cow.CanWrite());
+
+ aValue->Go();
+
+ EXPECT_EQ(0, stats.mCalls);
+ EXPECT_EQ(1, stats.mConstCalls);
+ },
+ []() {
+ // This gets called if we can't read. We shouldn't get here.
+ EXPECT_TRUE(false);
+ });
+ });
+
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_EQ(0, stats.mCalls);
+ EXPECT_EQ(1, stats.mConstCalls);
+ }
+
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(1, stats.mFrees);
+}
+
+TEST(ImageCopyOnWrite, Write)
+{
+ ValueStats stats;
+
+ {
+ CopyOnWrite<Value> cow(new Value(stats));
+
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_TRUE(cow.CanRead());
+ EXPECT_TRUE(cow.CanWrite());
+
+ cow.Write([&](Value* aValue) {
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_EQ(0, aValue->Serial());
+ EXPECT_TRUE(!cow.CanRead());
+ EXPECT_TRUE(!cow.CanWrite());
+
+ aValue->Go();
+
+ EXPECT_EQ(1, stats.mCalls);
+ EXPECT_EQ(0, stats.mConstCalls);
+ });
+
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_EQ(1, stats.mCalls);
+ EXPECT_EQ(0, stats.mConstCalls);
+ }
+
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(1, stats.mFrees);
+}
+
+TEST(ImageCopyOnWrite, WriteRecursive)
+{
+ ValueStats stats;
+
+ {
+ CopyOnWrite<Value> cow(new Value(stats));
+
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_TRUE(cow.CanRead());
+ EXPECT_TRUE(cow.CanWrite());
+
+ cow.Read([&](const Value* aValue) {
+ EXPECT_EQ(0, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_EQ(0, aValue->Serial());
+ EXPECT_TRUE(cow.CanRead());
+ EXPECT_TRUE(cow.CanWrite());
+
+ // Make sure Write() inside a Read() succeeds.
+ cow.Write(
+ [&](Value* aValue) {
+ EXPECT_EQ(1, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_EQ(1, aValue->Serial());
+ EXPECT_TRUE(!cow.CanRead());
+ EXPECT_TRUE(!cow.CanWrite());
+
+ aValue->Go();
+
+ EXPECT_EQ(1, stats.mCalls);
+ EXPECT_EQ(0, stats.mConstCalls);
+
+ // Make sure Read() inside a Write() fails.
+ cow.Read(
+ [](const Value* aValue) {
+ // This gets called if we can read. We shouldn't get here.
+ EXPECT_TRUE(false);
+ },
+ []() {
+ // This gets called if we can't read. We *should* get here.
+ EXPECT_TRUE(true);
+ });
+
+ // Make sure Write() inside a Write() fails.
+ cow.Write(
+ [](Value* aValue) {
+ // This gets called if we can write. We shouldn't get here.
+ EXPECT_TRUE(false);
+ },
+ []() {
+ // This gets called if we can't write. We *should* get here.
+ EXPECT_TRUE(true);
+ });
+ },
+ []() {
+ // This gets called if we can't write. We shouldn't get here.
+ EXPECT_TRUE(false);
+ });
+
+ aValue->Go();
+
+ EXPECT_EQ(1, stats.mCopies);
+ EXPECT_EQ(0, stats.mFrees);
+ EXPECT_EQ(1, stats.mCalls);
+ EXPECT_EQ(1, stats.mConstCalls);
+ });
+
+ EXPECT_EQ(1, stats.mCopies);
+ EXPECT_EQ(1, stats.mFrees);
+ EXPECT_EQ(1, stats.mCalls);
+ EXPECT_EQ(1, stats.mConstCalls);
+ }
+
+ EXPECT_EQ(1, stats.mCopies);
+ EXPECT_EQ(2, stats.mFrees);
+}
diff --git a/image/test/gtest/TestDecodeToSurface.cpp b/image/test/gtest/TestDecodeToSurface.cpp
new file mode 100644
index 0000000000..838f957c43
--- /dev/null
+++ b/image/test/gtest/TestDecodeToSurface.cpp
@@ -0,0 +1,173 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "Common.h"
+#include "imgIContainer.h"
+#include "ImageOps.h"
+#include "mozilla/gfx/2D.h"
+#include "nsComponentManagerUtils.h"
+#include "nsCOMPtr.h"
+#include "nsIInputStream.h"
+#include "nsIRunnable.h"
+#include "nsIThread.h"
+#include "mozilla/RefPtr.h"
+#include "nsString.h"
+#include "nsThreadUtils.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+class DecodeToSurfaceRunnable : public Runnable {
+ public:
+ DecodeToSurfaceRunnable(RefPtr<SourceSurface>& aSurface,
+ nsIInputStream* aInputStream,
+ ImageOps::ImageBuffer* aImageBuffer,
+ const ImageTestCase& aTestCase)
+ : mozilla::Runnable("DecodeToSurfaceRunnable"),
+ mSurface(aSurface),
+ mInputStream(aInputStream),
+ mImageBuffer(aImageBuffer),
+ mTestCase(aTestCase) {}
+
+ NS_IMETHOD Run() override {
+ Go();
+ return NS_OK;
+ }
+
+ void Go() {
+ Maybe<IntSize> outputSize;
+ if (mTestCase.mOutputSize != mTestCase.mSize) {
+ outputSize.emplace(mTestCase.mOutputSize);
+ }
+
+ uint32_t flags = FromSurfaceFlags(mTestCase.mSurfaceFlags);
+
+ if (mImageBuffer) {
+ mSurface = ImageOps::DecodeToSurface(
+ mImageBuffer, nsDependentCString(mTestCase.mMimeType), flags,
+ outputSize);
+ } else {
+ mSurface = ImageOps::DecodeToSurface(
+ mInputStream.forget(), nsDependentCString(mTestCase.mMimeType), flags,
+ outputSize);
+ }
+ ASSERT_TRUE(mSurface != nullptr);
+
+ EXPECT_TRUE(mSurface->IsDataSourceSurface());
+ EXPECT_TRUE(mSurface->GetFormat() == SurfaceFormat::OS_RGBX ||
+ mSurface->GetFormat() == SurfaceFormat::OS_RGBA);
+
+ if (outputSize) {
+ EXPECT_EQ(*outputSize, mSurface->GetSize());
+ } else {
+ EXPECT_EQ(mTestCase.mSize, mSurface->GetSize());
+ }
+
+ EXPECT_TRUE(IsSolidColor(mSurface, mTestCase.Color(), mTestCase.Fuzz()));
+ }
+
+ private:
+ RefPtr<SourceSurface>& mSurface;
+ nsCOMPtr<nsIInputStream> mInputStream;
+ RefPtr<ImageOps::ImageBuffer> mImageBuffer;
+ ImageTestCase mTestCase;
+};
+
+static void RunDecodeToSurface(const ImageTestCase& aTestCase,
+ ImageOps::ImageBuffer* aImageBuffer = nullptr) {
+ nsCOMPtr<nsIInputStream> inputStream;
+ if (!aImageBuffer) {
+ inputStream = LoadFile(aTestCase.mPath);
+ ASSERT_TRUE(inputStream != nullptr);
+ }
+
+ nsCOMPtr<nsIThread> thread;
+ nsresult rv =
+ NS_NewNamedThread("DecodeToSurface", getter_AddRefs(thread), nullptr);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // We run the DecodeToSurface tests off-main-thread to ensure that
+ // DecodeToSurface doesn't require any main-thread-only code.
+ RefPtr<SourceSurface> surface;
+ nsCOMPtr<nsIRunnable> runnable = new DecodeToSurfaceRunnable(
+ surface, inputStream, aImageBuffer, aTestCase);
+ NS_DispatchAndSpinEventLoopUntilComplete("RunDecodeToSurface"_ns, thread,
+ do_AddRef(runnable));
+
+ thread->Shutdown();
+
+ // Explicitly release the SourceSurface on the main thread.
+ surface = nullptr;
+}
+
+class ImageDecodeToSurface : public ::testing::Test {
+ protected:
+ AutoInitializeImageLib mInit;
+};
+
+TEST_F(ImageDecodeToSurface, PNG) { RunDecodeToSurface(GreenPNGTestCase()); }
+TEST_F(ImageDecodeToSurface, GIF) { RunDecodeToSurface(GreenGIFTestCase()); }
+TEST_F(ImageDecodeToSurface, JPG) { RunDecodeToSurface(GreenJPGTestCase()); }
+TEST_F(ImageDecodeToSurface, BMP) { RunDecodeToSurface(GreenBMPTestCase()); }
+TEST_F(ImageDecodeToSurface, ICO) { RunDecodeToSurface(GreenICOTestCase()); }
+TEST_F(ImageDecodeToSurface, Icon) { RunDecodeToSurface(GreenIconTestCase()); }
+TEST_F(ImageDecodeToSurface, WebP) { RunDecodeToSurface(GreenWebPTestCase()); }
+
+TEST_F(ImageDecodeToSurface, AnimatedGIF) {
+ RunDecodeToSurface(GreenFirstFrameAnimatedGIFTestCase());
+}
+
+TEST_F(ImageDecodeToSurface, AnimatedPNG) {
+ RunDecodeToSurface(GreenFirstFrameAnimatedPNGTestCase());
+}
+
+TEST_F(ImageDecodeToSurface, Corrupt) {
+ ImageTestCase testCase = CorruptTestCase();
+
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(testCase.mPath);
+ ASSERT_TRUE(inputStream != nullptr);
+
+ RefPtr<SourceSurface> surface = ImageOps::DecodeToSurface(
+ inputStream.forget(), nsDependentCString(testCase.mMimeType),
+ imgIContainer::DECODE_FLAGS_DEFAULT);
+ EXPECT_TRUE(surface == nullptr);
+}
+
+TEST_F(ImageDecodeToSurface, ICOMultipleSizes) {
+ ImageTestCase testCase = GreenMultipleSizesICOTestCase();
+
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(testCase.mPath);
+ ASSERT_TRUE(inputStream != nullptr);
+
+ RefPtr<ImageOps::ImageBuffer> buffer =
+ ImageOps::CreateImageBuffer(inputStream.forget());
+ ASSERT_TRUE(buffer != nullptr);
+
+ ImageMetadata metadata;
+ nsresult rv = ImageOps::DecodeMetadata(
+ buffer, nsDependentCString(testCase.mMimeType), metadata);
+ EXPECT_NS_SUCCEEDED(rv);
+ ASSERT_TRUE(metadata.HasSize());
+ EXPECT_EQ(testCase.mSize, metadata.GetSize().ToUnknownSize());
+
+ const nsTArray<OrientedIntSize>& nativeSizes = metadata.GetNativeSizes();
+ ASSERT_EQ(6u, nativeSizes.Length());
+
+ OrientedIntSize expectedSizes[] = {
+ OrientedIntSize(16, 16), OrientedIntSize(32, 32),
+ OrientedIntSize(64, 64), OrientedIntSize(128, 128),
+ OrientedIntSize(256, 256), OrientedIntSize(256, 128),
+ };
+
+ for (int i = 0; i < 6; ++i) {
+ EXPECT_EQ(expectedSizes[i], nativeSizes[i]);
+
+ // Request decoding at native size
+ testCase.mOutputSize = nativeSizes[i].ToUnknownSize();
+ RunDecodeToSurface(testCase, buffer);
+ }
+}
diff --git a/image/test/gtest/TestDecoders.cpp b/image/test/gtest/TestDecoders.cpp
new file mode 100644
index 0000000000..f043b011d0
--- /dev/null
+++ b/image/test/gtest/TestDecoders.cpp
@@ -0,0 +1,1142 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "Common.h"
+#include "AnimationSurfaceProvider.h"
+#include "DecodePool.h"
+#include "Decoder.h"
+#include "DecoderFactory.h"
+#include "decoders/nsBMPDecoder.h"
+#include "IDecodingTask.h"
+#include "ImageOps.h"
+#include "imgIContainer.h"
+#include "ImageFactory.h"
+#include "mozilla/ScopeExit.h"
+#include "mozilla/gfx/2D.h"
+#include "nsComponentManagerUtils.h"
+#include "nsCOMPtr.h"
+#include "nsIInputStream.h"
+#include "mozilla/RefPtr.h"
+#include "nsStreamUtils.h"
+#include "nsString.h"
+#include "nsThreadUtils.h"
+#include "ProgressTracker.h"
+#include "SourceBuffer.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+static already_AddRefed<SourceSurface> CheckDecoderState(
+ const ImageTestCase& aTestCase, image::Decoder* aDecoder) {
+ // image::Decoder should match what we asked for in the MIME type.
+ EXPECT_NE(aDecoder->GetType(), DecoderType::UNKNOWN);
+ EXPECT_EQ(aDecoder->GetType(),
+ DecoderFactory::GetDecoderType(aTestCase.mMimeType));
+
+ EXPECT_TRUE(aDecoder->GetDecodeDone());
+ EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_HAS_ERROR), aDecoder->HasError());
+
+ // Verify that the decoder made the expected progress.
+ Progress progress = aDecoder->TakeProgress();
+ EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_HAS_ERROR),
+ bool(progress & FLAG_HAS_ERROR));
+
+ if (aTestCase.mFlags & TEST_CASE_HAS_ERROR) {
+ return nullptr; // That's all we can check for bad images.
+ }
+
+ EXPECT_TRUE(bool(progress & FLAG_SIZE_AVAILABLE));
+ EXPECT_TRUE(bool(progress & FLAG_DECODE_COMPLETE));
+ EXPECT_TRUE(bool(progress & FLAG_FRAME_COMPLETE));
+ EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_TRANSPARENT),
+ bool(progress & FLAG_HAS_TRANSPARENCY));
+ EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_ANIMATED),
+ bool(progress & FLAG_IS_ANIMATED));
+
+ // The decoder should get the correct size.
+ OrientedIntSize size = aDecoder->Size();
+ EXPECT_EQ(aTestCase.mSize.width, size.width);
+ EXPECT_EQ(aTestCase.mSize.height, size.height);
+
+ // Get the current frame, which is always the first frame of the image
+ // because CreateAnonymousDecoder() forces a first-frame-only decode.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+
+ // Verify that the resulting surfaces matches our expectations.
+ EXPECT_TRUE(surface->IsDataSourceSurface());
+ EXPECT_TRUE(surface->GetFormat() == SurfaceFormat::OS_RGBX ||
+ surface->GetFormat() == SurfaceFormat::OS_RGBA);
+ EXPECT_EQ(aTestCase.mOutputSize, surface->GetSize());
+
+ return surface.forget();
+}
+
+static void CheckDecoderResults(const ImageTestCase& aTestCase,
+ image::Decoder* aDecoder) {
+ RefPtr<SourceSurface> surface = CheckDecoderState(aTestCase, aDecoder);
+ if (!surface) {
+ return;
+ }
+
+ if (aTestCase.mFlags & TEST_CASE_IGNORE_OUTPUT) {
+ return;
+ }
+
+ // Check the output.
+ EXPECT_TRUE(IsSolidColor(surface, aTestCase.Color(), aTestCase.Fuzz()));
+}
+
+template <typename Func>
+void WithBadBufferDecode(const ImageTestCase& aTestCase,
+ const Maybe<IntSize>& aOutputSize,
+ Func aResultChecker) {
+ // Prepare a SourceBuffer with an error that will immediately move iterators
+ // to COMPLETE.
+ auto sourceBuffer = MakeNotNull<RefPtr<SourceBuffer>>();
+ sourceBuffer->ExpectLength(SIZE_MAX);
+
+ // Create a decoder.
+ DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType);
+ RefPtr<image::Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(
+ decoderType, sourceBuffer, aOutputSize, DecoderFlags::FIRST_FRAME_ONLY,
+ aTestCase.mSurfaceFlags);
+ ASSERT_TRUE(decoder != nullptr);
+ RefPtr<IDecodingTask> task =
+ new AnonymousDecodingTask(WrapNotNull(decoder), /* aResumable */ false);
+
+ // Run the full decoder synchronously on the main thread.
+ task->Run();
+
+ // Call the lambda to verify the expected results.
+ aResultChecker(decoder);
+}
+
+static void CheckDecoderBadBuffer(const ImageTestCase& aTestCase) {
+ WithBadBufferDecode(aTestCase, Nothing(), [&](image::Decoder* aDecoder) {
+ CheckDecoderResults(aTestCase, aDecoder);
+ });
+}
+
+template <typename Func>
+void WithSingleChunkDecode(const ImageTestCase& aTestCase,
+ const Maybe<IntSize>& aOutputSize,
+ bool aUseDecodePool, Func aResultChecker) {
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
+ ASSERT_TRUE(inputStream != nullptr);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ nsresult rv = inputStream->Available(&length);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Write the data into a SourceBuffer.
+ auto sourceBuffer = MakeNotNull<RefPtr<SourceBuffer>>();
+ sourceBuffer->ExpectLength(length);
+ rv = sourceBuffer->AppendFromInputStream(inputStream, length);
+ ASSERT_NS_SUCCEEDED(rv);
+ sourceBuffer->Complete(NS_OK);
+
+ // Create a decoder.
+ DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType);
+ DecoderFlags decoderFlags =
+ DecoderFactory::GetDefaultDecoderFlagsForType(decoderType) |
+ DecoderFlags::FIRST_FRAME_ONLY;
+ RefPtr<image::Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(
+ decoderType, sourceBuffer, aOutputSize, decoderFlags,
+ aTestCase.mSurfaceFlags);
+ ASSERT_TRUE(decoder != nullptr);
+ RefPtr<IDecodingTask> task =
+ new AnonymousDecodingTask(WrapNotNull(decoder), /* aResumable */ false);
+
+ if (aUseDecodePool) {
+ DecodePool::Singleton()->AsyncRun(task.get());
+
+ while (!decoder->GetDecodeDone()) {
+ task->Resume();
+ }
+ } else { // Run the full decoder synchronously on the main thread.
+ task->Run();
+ }
+
+ // Call the lambda to verify the expected results.
+ aResultChecker(decoder);
+}
+
+static void CheckDecoderSingleChunk(const ImageTestCase& aTestCase,
+ bool aUseDecodePool = false) {
+ WithSingleChunkDecode(aTestCase, Nothing(), aUseDecodePool,
+ [&](image::Decoder* aDecoder) {
+ CheckDecoderResults(aTestCase, aDecoder);
+ });
+}
+
+template <typename Func>
+void WithDelayedChunkDecode(const ImageTestCase& aTestCase,
+ const Maybe<IntSize>& aOutputSize,
+ Func aResultChecker) {
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
+ ASSERT_TRUE(inputStream != nullptr);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ nsresult rv = inputStream->Available(&length);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Prepare an empty SourceBuffer.
+ auto sourceBuffer = MakeNotNull<RefPtr<SourceBuffer>>();
+
+ // Create a decoder.
+ DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType);
+ RefPtr<image::Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(
+ decoderType, sourceBuffer, aOutputSize, DecoderFlags::FIRST_FRAME_ONLY,
+ aTestCase.mSurfaceFlags);
+ ASSERT_TRUE(decoder != nullptr);
+ RefPtr<IDecodingTask> task =
+ new AnonymousDecodingTask(WrapNotNull(decoder), /* aResumable */ true);
+
+ // Run the full decoder synchronously. It should now be waiting on
+ // the iterator to yield some data since we haven't written anything yet.
+ task->Run();
+
+ // Writing all of the data should wake up the decoder to complete.
+ sourceBuffer->ExpectLength(length);
+ rv = sourceBuffer->AppendFromInputStream(inputStream, length);
+ ASSERT_NS_SUCCEEDED(rv);
+ sourceBuffer->Complete(NS_OK);
+
+ // It would have gotten posted to the main thread to avoid mutex contention.
+ SpinPendingEvents();
+
+ // Call the lambda to verify the expected results.
+ aResultChecker(decoder);
+}
+
+static void CheckDecoderDelayedChunk(const ImageTestCase& aTestCase) {
+ WithDelayedChunkDecode(aTestCase, Nothing(), [&](image::Decoder* aDecoder) {
+ CheckDecoderResults(aTestCase, aDecoder);
+ });
+}
+
+static void CheckDecoderMultiChunk(const ImageTestCase& aTestCase,
+ uint64_t aChunkSize = 1) {
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
+ ASSERT_TRUE(inputStream != nullptr);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ nsresult rv = inputStream->Available(&length);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Create a SourceBuffer and a decoder.
+ auto sourceBuffer = MakeNotNull<RefPtr<SourceBuffer>>();
+ sourceBuffer->ExpectLength(length);
+ DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType);
+ DecoderFlags decoderFlags =
+ DecoderFactory::GetDefaultDecoderFlagsForType(decoderType) |
+ DecoderFlags::FIRST_FRAME_ONLY;
+ RefPtr<image::Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(
+ decoderType, sourceBuffer, Nothing(), decoderFlags,
+ aTestCase.mSurfaceFlags);
+ ASSERT_TRUE(decoder != nullptr);
+ RefPtr<IDecodingTask> task =
+ new AnonymousDecodingTask(WrapNotNull(decoder), /* aResumable */ true);
+
+ // Run the full decoder synchronously. It should now be waiting on
+ // the iterator to yield some data since we haven't written anything yet.
+ task->Run();
+
+ while (length > 0) {
+ uint64_t read = length > aChunkSize ? aChunkSize : length;
+ length -= read;
+
+ uint64_t available = 0;
+ rv = inputStream->Available(&available);
+ ASSERT_TRUE(available >= read);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Writing any data should wake up the decoder to complete.
+ rv = sourceBuffer->AppendFromInputStream(inputStream, read);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // It would have gotten posted to the main thread to avoid mutex contention.
+ SpinPendingEvents();
+ }
+
+ sourceBuffer->Complete(NS_OK);
+ SpinPendingEvents();
+
+ CheckDecoderResults(aTestCase, decoder);
+}
+
+static void CheckDownscaleDuringDecode(const ImageTestCase& aTestCase) {
+ // This function expects that |aTestCase| consists of 25 lines of green,
+ // followed by 25 lines of red, followed by 25 lines of green, followed by 25
+ // more lines of red. We'll downscale it from 100x100 to 20x20.
+ IntSize outputSize(20, 20);
+
+ WithSingleChunkDecode(
+ aTestCase, Some(outputSize), /* aUseDecodePool */ false,
+ [&](image::Decoder* aDecoder) {
+ RefPtr<SourceSurface> surface = CheckDecoderState(aTestCase, aDecoder);
+
+ // There are no downscale-during-decode tests that have
+ // TEST_CASE_HAS_ERROR set, so we expect to always get a surface here.
+ EXPECT_TRUE(surface != nullptr);
+
+ if (aTestCase.mFlags & TEST_CASE_IGNORE_OUTPUT) {
+ return;
+ }
+
+ // Check that the downscaled image is correct. Note that we skip rows
+ // near the transitions between colors, since the downscaler does not
+ // produce a sharp boundary at these points. Even some of the rows we
+ // test need a small amount of fuzz; this is just the nature of Lanczos
+ // downscaling.
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 4,
+ aTestCase.ChooseColor(BGRAColor::Green()),
+ /* aFuzz = */ 47));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 6, 3,
+ aTestCase.ChooseColor(BGRAColor::Red()),
+ /* aFuzz = */ 27));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 11, 3, BGRAColor::Green(),
+ /* aFuzz = */ 47));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 16, 4,
+ aTestCase.ChooseColor(BGRAColor::Red()),
+ /* aFuzz = */ 27));
+ });
+}
+
+static void CheckAnimationDecoderResults(const ImageTestCase& aTestCase,
+ AnimationSurfaceProvider* aProvider,
+ image::Decoder* aDecoder) {
+ EXPECT_TRUE(aDecoder->GetDecodeDone());
+ EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_HAS_ERROR), aDecoder->HasError());
+
+ if (aTestCase.mFlags & TEST_CASE_HAS_ERROR) {
+ return; // That's all we can check for bad images.
+ }
+
+ // The decoder should get the correct size.
+ OrientedIntSize size = aDecoder->Size();
+ EXPECT_EQ(aTestCase.mSize.width, size.width);
+ EXPECT_EQ(aTestCase.mSize.height, size.height);
+
+ if (aTestCase.mFlags & TEST_CASE_IGNORE_OUTPUT) {
+ return;
+ }
+
+ // Check the output.
+ AutoTArray<BGRAColor, 2> framePixels;
+ framePixels.AppendElement(aTestCase.ChooseColor(BGRAColor::Green()));
+ framePixels.AppendElement(
+ aTestCase.ChooseColor(BGRAColor(0x7F, 0x7F, 0x7F, 0xFF)));
+
+ DrawableSurface drawableSurface(WrapNotNull(aProvider));
+ for (size_t i = 0; i < framePixels.Length(); ++i) {
+ nsresult rv = drawableSurface.Seek(i);
+ EXPECT_NS_SUCCEEDED(rv);
+
+ // Check the first frame, all green.
+ RawAccessFrameRef rawFrame = drawableSurface->RawAccessRef();
+ RefPtr<SourceSurface> surface = rawFrame->GetSourceSurface();
+
+ // Verify that the resulting surfaces matches our expectations.
+ EXPECT_TRUE(surface->IsDataSourceSurface());
+ EXPECT_TRUE(surface->GetFormat() == SurfaceFormat::OS_RGBX ||
+ surface->GetFormat() == SurfaceFormat::OS_RGBA);
+ EXPECT_EQ(aTestCase.mOutputSize, surface->GetSize());
+ EXPECT_TRUE(IsSolidColor(surface, framePixels[i], aTestCase.Fuzz()));
+ }
+
+ // Should be no more frames.
+ nsresult rv = drawableSurface.Seek(framePixels.Length());
+ EXPECT_NS_FAILED(rv);
+}
+
+template <typename Func>
+static void WithSingleChunkAnimationDecode(const ImageTestCase& aTestCase,
+ Func aResultChecker) {
+ // Create an image.
+ RefPtr<Image> image = ImageFactory::CreateAnonymousImage(
+ nsDependentCString(aTestCase.mMimeType));
+ ASSERT_TRUE(!image->HasError());
+
+ NotNull<RefPtr<RasterImage>> rasterImage =
+ WrapNotNull(static_cast<RasterImage*>(image.get()));
+
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
+ ASSERT_TRUE(inputStream != nullptr);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ nsresult rv = inputStream->Available(&length);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Write the data into a SourceBuffer.
+ NotNull<RefPtr<SourceBuffer>> sourceBuffer = WrapNotNull(new SourceBuffer());
+ sourceBuffer->ExpectLength(length);
+ rv = sourceBuffer->AppendFromInputStream(inputStream, length);
+ ASSERT_NS_SUCCEEDED(rv);
+ sourceBuffer->Complete(NS_OK);
+
+ // Create a metadata decoder first, because otherwise RasterImage will get
+ // unhappy about finding out the image is animated during a full decode.
+ DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType);
+ DecoderFlags decoderFlags =
+ DecoderFactory::GetDefaultDecoderFlagsForType(decoderType);
+ RefPtr<IDecodingTask> task = DecoderFactory::CreateMetadataDecoder(
+ decoderType, rasterImage, decoderFlags, sourceBuffer);
+ ASSERT_TRUE(task != nullptr);
+
+ // Run the metadata decoder synchronously.
+ task->Run();
+
+ // Create a decoder.
+ SurfaceFlags surfaceFlags = aTestCase.mSurfaceFlags;
+ RefPtr<image::Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(
+ decoderType, sourceBuffer, Nothing(), decoderFlags, surfaceFlags);
+ ASSERT_TRUE(decoder != nullptr);
+
+ // Create an AnimationSurfaceProvider which will manage the decoding process
+ // and make this decoder's output available in the surface cache.
+ SurfaceKey surfaceKey = RasterSurfaceKey(aTestCase.mOutputSize, surfaceFlags,
+ PlaybackType::eAnimated);
+ RefPtr<AnimationSurfaceProvider> provider = new AnimationSurfaceProvider(
+ rasterImage, surfaceKey, WrapNotNull(decoder),
+ /* aCurrentFrame */ 0);
+
+ // Run the full decoder synchronously.
+ provider->Run();
+
+ // Call the lambda to verify the expected results.
+ aResultChecker(provider, decoder);
+}
+
+static void CheckAnimationDecoderSingleChunk(const ImageTestCase& aTestCase) {
+ WithSingleChunkAnimationDecode(
+ aTestCase,
+ [&](AnimationSurfaceProvider* aProvider, image::Decoder* aDecoder) {
+ CheckAnimationDecoderResults(aTestCase, aProvider, aDecoder);
+ });
+}
+
+static void CheckDecoderFrameFirst(const ImageTestCase& aTestCase) {
+ // Verify that we can decode this test case and retrieve the first frame using
+ // imgIContainer::FRAME_FIRST. This ensures that we correctly trigger a
+ // single-frame decode rather than an animated decode when
+ // imgIContainer::FRAME_FIRST is requested.
+
+ // Create an image.
+ RefPtr<Image> image = ImageFactory::CreateAnonymousImage(
+ nsDependentCString(aTestCase.mMimeType));
+ ASSERT_TRUE(!image->HasError());
+
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
+ ASSERT_TRUE(inputStream);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ nsresult rv = inputStream->Available(&length);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Write the data into the image.
+ rv = image->OnImageDataAvailable(nullptr, inputStream, 0,
+ static_cast<uint32_t>(length));
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Let the image know we've sent all the data.
+ rv = image->OnImageDataComplete(nullptr, NS_OK, true);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
+ tracker->SyncNotifyProgress(FLAG_LOAD_COMPLETE);
+
+ // Lock the image so its surfaces don't disappear during the test.
+ image->LockImage();
+
+ auto unlock = mozilla::MakeScopeExit([&] { image->UnlockImage(); });
+
+ // Use GetFrame() to force a sync decode of the image, specifying FRAME_FIRST
+ // to ensure that we don't get an animated decode.
+ RefPtr<SourceSurface> surface = image->GetFrame(
+ imgIContainer::FRAME_FIRST, imgIContainer::FLAG_SYNC_DECODE);
+
+ // Ensure that the image's metadata meets our expectations.
+ IntSize imageSize(0, 0);
+ rv = image->GetWidth(&imageSize.width);
+ EXPECT_NS_SUCCEEDED(rv);
+ rv = image->GetHeight(&imageSize.height);
+ EXPECT_NS_SUCCEEDED(rv);
+
+ EXPECT_EQ(aTestCase.mSize.width, imageSize.width);
+ EXPECT_EQ(aTestCase.mSize.height, imageSize.height);
+
+ Progress imageProgress = tracker->GetProgress();
+
+ EXPECT_TRUE(bool(imageProgress & FLAG_HAS_TRANSPARENCY) == false);
+ EXPECT_TRUE(bool(imageProgress & FLAG_IS_ANIMATED) == true);
+
+ // Ensure that we decoded the static version of the image.
+ {
+ LookupResult result = SurfaceCache::Lookup(
+ ImageKey(image.get()),
+ RasterSurfaceKey(imageSize, aTestCase.mSurfaceFlags,
+ PlaybackType::eStatic),
+ /* aMarkUsed = */ false);
+ ASSERT_EQ(MatchType::EXACT, result.Type());
+ EXPECT_TRUE(bool(result.Surface()));
+ }
+
+ // Ensure that we didn't decode the animated version of the image.
+ {
+ LookupResult result = SurfaceCache::Lookup(
+ ImageKey(image.get()),
+ RasterSurfaceKey(imageSize, aTestCase.mSurfaceFlags,
+ PlaybackType::eAnimated),
+ /* aMarkUsed = */ false);
+ ASSERT_EQ(MatchType::NOT_FOUND, result.Type());
+ }
+
+ // Use GetFrame() to force a sync decode of the image, this time specifying
+ // FRAME_CURRENT to ensure that we get an animated decode.
+ RefPtr<SourceSurface> animatedSurface = image->GetFrame(
+ imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE);
+
+ // Ensure that we decoded both frames of the animated version of the image.
+ {
+ LookupResult result = SurfaceCache::Lookup(
+ ImageKey(image.get()),
+ RasterSurfaceKey(imageSize, aTestCase.mSurfaceFlags,
+ PlaybackType::eAnimated),
+ /* aMarkUsed = */ true);
+ ASSERT_EQ(MatchType::EXACT, result.Type());
+
+ EXPECT_NS_SUCCEEDED(result.Surface().Seek(0));
+ EXPECT_TRUE(bool(result.Surface()));
+
+ RefPtr<imgFrame> partialFrame = result.Surface().GetFrame(1);
+ EXPECT_TRUE(bool(partialFrame));
+ }
+
+ // Ensure that the static version is still around.
+ {
+ LookupResult result = SurfaceCache::Lookup(
+ ImageKey(image.get()),
+ RasterSurfaceKey(imageSize, aTestCase.mSurfaceFlags,
+ PlaybackType::eStatic),
+ /* aMarkUsed = */ true);
+ ASSERT_EQ(MatchType::EXACT, result.Type());
+ EXPECT_TRUE(bool(result.Surface()));
+ }
+}
+
+static void CheckDecoderFrameCurrent(const ImageTestCase& aTestCase) {
+ // Verify that we can decode this test case and retrieve the entire sequence
+ // of frames using imgIContainer::FRAME_CURRENT. This ensures that we
+ // correctly trigger an animated decode rather than a single-frame decode when
+ // imgIContainer::FRAME_CURRENT is requested.
+
+ // Create an image.
+ RefPtr<Image> image = ImageFactory::CreateAnonymousImage(
+ nsDependentCString(aTestCase.mMimeType));
+ ASSERT_TRUE(!image->HasError());
+
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
+ ASSERT_TRUE(inputStream);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ nsresult rv = inputStream->Available(&length);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Write the data into the image.
+ rv = image->OnImageDataAvailable(nullptr, inputStream, 0,
+ static_cast<uint32_t>(length));
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Let the image know we've sent all the data.
+ rv = image->OnImageDataComplete(nullptr, NS_OK, true);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
+ tracker->SyncNotifyProgress(FLAG_LOAD_COMPLETE);
+
+ // Lock the image so its surfaces don't disappear during the test.
+ image->LockImage();
+
+ // Use GetFrame() to force a sync decode of the image, specifying
+ // FRAME_CURRENT to ensure we get an animated decode.
+ RefPtr<SourceSurface> surface = image->GetFrame(
+ imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE);
+
+ // Ensure that the image's metadata meets our expectations.
+ IntSize imageSize(0, 0);
+ rv = image->GetWidth(&imageSize.width);
+ EXPECT_NS_SUCCEEDED(rv);
+ rv = image->GetHeight(&imageSize.height);
+ EXPECT_NS_SUCCEEDED(rv);
+
+ EXPECT_EQ(aTestCase.mSize.width, imageSize.width);
+ EXPECT_EQ(aTestCase.mSize.height, imageSize.height);
+
+ Progress imageProgress = tracker->GetProgress();
+
+ EXPECT_TRUE(bool(imageProgress & FLAG_HAS_TRANSPARENCY) == false);
+ EXPECT_TRUE(bool(imageProgress & FLAG_IS_ANIMATED) == true);
+
+ // Ensure that we decoded both frames of the animated version of the image.
+ {
+ LookupResult result = SurfaceCache::Lookup(
+ ImageKey(image.get()),
+ RasterSurfaceKey(imageSize, aTestCase.mSurfaceFlags,
+ PlaybackType::eAnimated),
+ /* aMarkUsed = */ true);
+ ASSERT_EQ(MatchType::EXACT, result.Type());
+
+ EXPECT_NS_SUCCEEDED(result.Surface().Seek(0));
+ EXPECT_TRUE(bool(result.Surface()));
+
+ RefPtr<imgFrame> partialFrame = result.Surface().GetFrame(1);
+ EXPECT_TRUE(bool(partialFrame));
+ }
+
+ // Ensure that we didn't decode the static version of the image.
+ {
+ LookupResult result = SurfaceCache::Lookup(
+ ImageKey(image.get()),
+ RasterSurfaceKey(imageSize, aTestCase.mSurfaceFlags,
+ PlaybackType::eStatic),
+ /* aMarkUsed = */ false);
+ ASSERT_EQ(MatchType::NOT_FOUND, result.Type());
+ }
+
+ // Use GetFrame() to force a sync decode of the image, this time specifying
+ // FRAME_FIRST to ensure that we get a single-frame decode.
+ RefPtr<SourceSurface> animatedSurface = image->GetFrame(
+ imgIContainer::FRAME_FIRST, imgIContainer::FLAG_SYNC_DECODE);
+
+ // Ensure that we decoded the static version of the image.
+ {
+ LookupResult result = SurfaceCache::Lookup(
+ ImageKey(image.get()),
+ RasterSurfaceKey(imageSize, aTestCase.mSurfaceFlags,
+ PlaybackType::eStatic),
+ /* aMarkUsed = */ true);
+ ASSERT_EQ(MatchType::EXACT, result.Type());
+ EXPECT_TRUE(bool(result.Surface()));
+ }
+
+ // Ensure that both frames of the animated version are still around.
+ {
+ LookupResult result = SurfaceCache::Lookup(
+ ImageKey(image.get()),
+ RasterSurfaceKey(imageSize, aTestCase.mSurfaceFlags,
+ PlaybackType::eAnimated),
+ /* aMarkUsed = */ true);
+ ASSERT_EQ(MatchType::EXACT, result.Type());
+
+ EXPECT_NS_SUCCEEDED(result.Surface().Seek(0));
+ EXPECT_TRUE(bool(result.Surface()));
+
+ RefPtr<imgFrame> partialFrame = result.Surface().GetFrame(1);
+ EXPECT_TRUE(bool(partialFrame));
+ }
+}
+
+class ImageDecoders : public ::testing::Test {
+ protected:
+ AutoInitializeImageLib mInit;
+};
+
+#define IMAGE_GTEST_DECODER_BASE_F(test_prefix) \
+ TEST_F(ImageDecoders, test_prefix##SingleChunk) { \
+ CheckDecoderSingleChunk(Green##test_prefix##TestCase()); \
+ } \
+ \
+ TEST_F(ImageDecoders, test_prefix##DelayedChunk) { \
+ CheckDecoderDelayedChunk(Green##test_prefix##TestCase()); \
+ } \
+ \
+ TEST_F(ImageDecoders, test_prefix##MultiChunk) { \
+ CheckDecoderMultiChunk(Green##test_prefix##TestCase()); \
+ } \
+ \
+ TEST_F(ImageDecoders, test_prefix##DownscaleDuringDecode) { \
+ CheckDownscaleDuringDecode(Downscaled##test_prefix##TestCase()); \
+ } \
+ \
+ TEST_F(ImageDecoders, test_prefix##ForceSRGB) { \
+ CheckDecoderSingleChunk(Green##test_prefix##TestCase().WithSurfaceFlags( \
+ SurfaceFlags::TO_SRGB_COLORSPACE)); \
+ } \
+ \
+ TEST_F(ImageDecoders, test_prefix##BadBuffer) { \
+ CheckDecoderBadBuffer(Green##test_prefix##TestCase().WithFlags( \
+ TEST_CASE_HAS_ERROR | TEST_CASE_IGNORE_OUTPUT)); \
+ }
+
+IMAGE_GTEST_DECODER_BASE_F(PNG)
+IMAGE_GTEST_DECODER_BASE_F(GIF)
+IMAGE_GTEST_DECODER_BASE_F(JPG)
+IMAGE_GTEST_DECODER_BASE_F(BMP)
+IMAGE_GTEST_DECODER_BASE_F(ICO)
+IMAGE_GTEST_DECODER_BASE_F(Icon)
+IMAGE_GTEST_DECODER_BASE_F(WebP)
+#ifdef MOZ_JXL
+IMAGE_GTEST_DECODER_BASE_F(JXL)
+#endif
+
+TEST_F(ImageDecoders, ICOWithANDMaskDownscaleDuringDecode) {
+ CheckDownscaleDuringDecode(DownscaledTransparentICOWithANDMaskTestCase());
+}
+
+TEST_F(ImageDecoders, WebPLargeMultiChunk) {
+ CheckDecoderMultiChunk(LargeWebPTestCase(), /* aChunkSize */ 64);
+}
+
+TEST_F(ImageDecoders, WebPIccSrgbMultiChunk) {
+ CheckDecoderMultiChunk(GreenWebPIccSrgbTestCase());
+}
+
+TEST_F(ImageDecoders, WebPTransparentSingleChunk) {
+ CheckDecoderSingleChunk(TransparentWebPTestCase());
+}
+
+TEST_F(ImageDecoders, WebPTransparentNoAlphaHeaderSingleChunk) {
+ CheckDecoderSingleChunk(TransparentNoAlphaHeaderWebPTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunk) {
+ CheckDecoderSingleChunk(GreenAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkNonzeroReserved) {
+ CheckDecoderSingleChunk(NonzeroReservedAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkMultipleColr) {
+ CheckDecoderSingleChunk(MultipleColrAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkTransparent10bit420) {
+ CheckDecoderSingleChunk(Transparent10bit420AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkTransparent10bit422) {
+ CheckDecoderSingleChunk(Transparent10bit422AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkTransparent10bit444) {
+ CheckDecoderSingleChunk(Transparent10bit444AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkTransparent12bit420) {
+ CheckDecoderSingleChunk(Transparent12bit420AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkTransparent12bit422) {
+ CheckDecoderSingleChunk(Transparent12bit422AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkTransparent12bit444) {
+ CheckDecoderSingleChunk(Transparent12bit444AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkTransparent8bit420) {
+ CheckDecoderSingleChunk(Transparent8bit420AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkTransparent8bit422) {
+ CheckDecoderSingleChunk(Transparent8bit422AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkTransparent8bit444) {
+ CheckDecoderSingleChunk(Transparent8bit444AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray8bitLimitedRangeBT601) {
+ CheckDecoderSingleChunk(Gray8bitLimitedRangeBT601AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray8bitLimitedRangeBT709) {
+ CheckDecoderSingleChunk(Gray8bitLimitedRangeBT709AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray8bitLimitedRangeBT2020) {
+ CheckDecoderSingleChunk(Gray8bitLimitedRangeBT2020AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray8bitFullRangeBT601) {
+ CheckDecoderSingleChunk(Gray8bitFullRangeBT601AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray8bitFullRangeBT709) {
+ CheckDecoderSingleChunk(Gray8bitFullRangeBT709AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray8bitFullRangeBT2020) {
+ CheckDecoderSingleChunk(Gray8bitFullRangeBT2020AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray10bitLimitedRangeBT601) {
+ CheckDecoderSingleChunk(Gray10bitLimitedRangeBT601AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray10bitLimitedRangeBT709) {
+ CheckDecoderSingleChunk(Gray10bitLimitedRangeBT709AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray10bitLimitedRangeBT2020) {
+ CheckDecoderSingleChunk(Gray10bitLimitedRangeBT2020AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray10bitFullRangeBT601) {
+ CheckDecoderSingleChunk(Gray10bitFullRangeBT601AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray10bitFullRangeBT709) {
+ CheckDecoderSingleChunk(Gray10bitFullRangeBT709AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray10bitFullRangeBT2020) {
+ CheckDecoderSingleChunk(Gray10bitFullRangeBT2020AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray12bitLimitedRangeBT601) {
+ CheckDecoderSingleChunk(Gray12bitLimitedRangeBT601AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray12bitLimitedRangeBT709) {
+ CheckDecoderSingleChunk(Gray12bitLimitedRangeBT709AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray12bitLimitedRangeBT2020) {
+ CheckDecoderSingleChunk(Gray12bitLimitedRangeBT2020AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray12bitFullRangeBT601) {
+ CheckDecoderSingleChunk(Gray12bitFullRangeBT601AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray12bitFullRangeBT709) {
+ CheckDecoderSingleChunk(Gray12bitFullRangeBT709AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray12bitFullRangeBT2020) {
+ CheckDecoderSingleChunk(Gray12bitFullRangeBT2020AVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray8bitLimitedRangeGrayscale) {
+ CheckDecoderSingleChunk(Gray8bitLimitedRangeGrayscaleAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray8bitFullRangeGrayscale) {
+ CheckDecoderSingleChunk(Gray8bitFullRangeGrayscaleAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray10bitLimitedRangeGrayscale) {
+ CheckDecoderSingleChunk(Gray10bitLimitedRangeGrayscaleAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray10bitFullRangeGrayscale) {
+ CheckDecoderSingleChunk(Gray10bitFullRangeGrayscaleAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray12bitLimitedRangeGrayscale) {
+ CheckDecoderSingleChunk(Gray12bitLimitedRangeGrayscaleAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFSingleChunkGray12bitFullRangeGrayscale) {
+ CheckDecoderSingleChunk(Gray12bitFullRangeGrayscaleAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFMultiLayerSingleChunk) {
+ CheckDecoderSingleChunk(MultiLayerAVIFTestCase());
+}
+
+// This test must use the decode pool in order to check for regressions
+// of crashing the dav1d decoder when the ImgDecoder threads have a standard-
+// sized stack.
+TEST_F(ImageDecoders, AVIFStackCheck) {
+ CheckDecoderSingleChunk(StackCheckAVIFTestCase(), /* aUseDecodePool */ true);
+}
+
+TEST_F(ImageDecoders, AVIFDelayedChunk) {
+ CheckDecoderDelayedChunk(GreenAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFMultiChunk) {
+ CheckDecoderMultiChunk(GreenAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AVIFLargeMultiChunk) {
+ CheckDecoderMultiChunk(LargeAVIFTestCase(), /* aChunkSize */ 64);
+}
+
+TEST_F(ImageDecoders, AVIFDownscaleDuringDecode) {
+ CheckDownscaleDuringDecode(DownscaledAVIFTestCase());
+}
+
+#ifdef MOZ_JXL
+TEST_F(ImageDecoders, JXLLargeMultiChunk) {
+ CheckDecoderMultiChunk(LargeJXLTestCase(), /* aChunkSize */ 64);
+}
+#endif
+
+TEST_F(ImageDecoders, AnimatedGIFSingleChunk) {
+ CheckDecoderSingleChunk(GreenFirstFrameAnimatedGIFTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedGIFMultiChunk) {
+ CheckDecoderMultiChunk(GreenFirstFrameAnimatedGIFTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedGIFWithBlendedFrames) {
+ CheckAnimationDecoderSingleChunk(GreenFirstFrameAnimatedGIFTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedPNGSingleChunk) {
+ CheckDecoderSingleChunk(GreenFirstFrameAnimatedPNGTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedPNGMultiChunk) {
+ CheckDecoderMultiChunk(GreenFirstFrameAnimatedPNGTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedPNGWithBlendedFrames) {
+ CheckAnimationDecoderSingleChunk(GreenFirstFrameAnimatedPNGTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedWebPSingleChunk) {
+ CheckDecoderSingleChunk(GreenFirstFrameAnimatedWebPTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedWebPMultiChunk) {
+ CheckDecoderMultiChunk(GreenFirstFrameAnimatedWebPTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedWebPWithBlendedFrames) {
+ CheckAnimationDecoderSingleChunk(GreenFirstFrameAnimatedWebPTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedAVIFSingleChunk) {
+ CheckDecoderSingleChunk(GreenFirstFrameAnimatedAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedAVIFMultiChunk) {
+ CheckDecoderMultiChunk(GreenFirstFrameAnimatedAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedAVIFWithBlendedFrames) {
+ CheckAnimationDecoderSingleChunk(GreenFirstFrameAnimatedAVIFTestCase());
+}
+
+TEST_F(ImageDecoders, CorruptSingleChunk) {
+ CheckDecoderSingleChunk(CorruptTestCase());
+}
+
+TEST_F(ImageDecoders, CorruptMultiChunk) {
+ CheckDecoderMultiChunk(CorruptTestCase());
+}
+
+TEST_F(ImageDecoders, CorruptBMPWithTruncatedHeaderSingleChunk) {
+ CheckDecoderSingleChunk(CorruptBMPWithTruncatedHeader());
+}
+
+TEST_F(ImageDecoders, CorruptBMPWithTruncatedHeaderMultiChunk) {
+ CheckDecoderMultiChunk(CorruptBMPWithTruncatedHeader());
+}
+
+TEST_F(ImageDecoders, CorruptICOWithBadBMPWidthSingleChunk) {
+ CheckDecoderSingleChunk(CorruptICOWithBadBMPWidthTestCase());
+}
+
+TEST_F(ImageDecoders, CorruptICOWithBadBMPWidthMultiChunk) {
+ CheckDecoderMultiChunk(CorruptICOWithBadBMPWidthTestCase());
+}
+
+TEST_F(ImageDecoders, CorruptICOWithBadBMPHeightSingleChunk) {
+ CheckDecoderSingleChunk(CorruptICOWithBadBMPHeightTestCase());
+}
+
+TEST_F(ImageDecoders, CorruptICOWithBadBMPHeightMultiChunk) {
+ CheckDecoderMultiChunk(CorruptICOWithBadBMPHeightTestCase());
+}
+
+TEST_F(ImageDecoders, CorruptICOWithBadBppSingleChunk) {
+ CheckDecoderSingleChunk(CorruptICOWithBadBppTestCase());
+}
+
+// Running this test under emulation for Android 7 on x86_64 seems to result
+// in the large allocation succeeding, but leaving so little memory left the
+// system falls over and it kills the test run, so we skip it instead.
+// See bug 1655846 for more details.
+#ifndef ANDROID
+TEST_F(ImageDecoders, CorruptAVIFSingleChunk) {
+ CheckDecoderSingleChunk(CorruptAVIFTestCase());
+}
+#endif
+
+TEST_F(ImageDecoders, AnimatedGIFWithFRAME_FIRST) {
+ CheckDecoderFrameFirst(GreenFirstFrameAnimatedGIFTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedGIFWithFRAME_CURRENT) {
+ CheckDecoderFrameCurrent(GreenFirstFrameAnimatedGIFTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedGIFWithExtraImageSubBlocks) {
+ ImageTestCase testCase = ExtraImageSubBlocksAnimatedGIFTestCase();
+
+ // Verify that we can decode this test case and get two frames, even though
+ // there are extra image sub blocks between the first and second frame. The
+ // extra data shouldn't confuse the decoder or cause the decode to fail.
+
+ // Create an image.
+ RefPtr<Image> image = TestCaseToDecodedImage(testCase);
+
+ // Ensure that the image's metadata meets our expectations.
+ IntSize imageSize(0, 0);
+ nsresult rv = image->GetWidth(&imageSize.width);
+ EXPECT_NS_SUCCEEDED(rv);
+ rv = image->GetHeight(&imageSize.height);
+ EXPECT_NS_SUCCEEDED(rv);
+
+ EXPECT_EQ(testCase.mSize.width, imageSize.width);
+ EXPECT_EQ(testCase.mSize.height, imageSize.height);
+
+ RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
+ Progress imageProgress = tracker->GetProgress();
+
+ EXPECT_TRUE(bool(imageProgress & FLAG_HAS_TRANSPARENCY) == false);
+ EXPECT_TRUE(bool(imageProgress & FLAG_IS_ANIMATED) == true);
+
+ // Ensure that we decoded both frames of the image.
+ LookupResult result =
+ SurfaceCache::Lookup(ImageKey(image.get()),
+ RasterSurfaceKey(imageSize, testCase.mSurfaceFlags,
+ PlaybackType::eAnimated),
+ /* aMarkUsed = */ true);
+ ASSERT_EQ(MatchType::EXACT, result.Type());
+
+ EXPECT_NS_SUCCEEDED(result.Surface().Seek(0));
+ EXPECT_TRUE(bool(result.Surface()));
+
+ RefPtr<imgFrame> partialFrame = result.Surface().GetFrame(1);
+ EXPECT_TRUE(bool(partialFrame));
+}
+
+TEST_F(ImageDecoders, AnimatedWebPWithFRAME_FIRST) {
+ CheckDecoderFrameFirst(GreenFirstFrameAnimatedWebPTestCase());
+}
+
+TEST_F(ImageDecoders, AnimatedWebPWithFRAME_CURRENT) {
+ CheckDecoderFrameCurrent(GreenFirstFrameAnimatedWebPTestCase());
+}
+
+TEST_F(ImageDecoders, TruncatedSmallGIFSingleChunk) {
+ CheckDecoderSingleChunk(TruncatedSmallGIFTestCase());
+}
+
+TEST_F(ImageDecoders, LargeICOWithBMPSingleChunk) {
+ CheckDecoderSingleChunk(LargeICOWithBMPTestCase());
+}
+
+TEST_F(ImageDecoders, LargeICOWithBMPMultiChunk) {
+ CheckDecoderMultiChunk(LargeICOWithBMPTestCase(), /* aChunkSize */ 64);
+}
+
+TEST_F(ImageDecoders, LargeICOWithPNGSingleChunk) {
+ CheckDecoderSingleChunk(LargeICOWithPNGTestCase());
+}
+
+TEST_F(ImageDecoders, LargeICOWithPNGMultiChunk) {
+ CheckDecoderMultiChunk(LargeICOWithPNGTestCase());
+}
+
+TEST_F(ImageDecoders, MultipleSizesICOSingleChunk) {
+ ImageTestCase testCase = GreenMultipleSizesICOTestCase();
+
+ // Create an image.
+ RefPtr<Image> image = ImageFactory::CreateAnonymousImage(
+ nsDependentCString(testCase.mMimeType));
+ ASSERT_TRUE(!image->HasError());
+
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(testCase.mPath);
+ ASSERT_TRUE(inputStream);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ nsresult rv = inputStream->Available(&length);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Write the data into the image.
+ rv = image->OnImageDataAvailable(nullptr, inputStream, 0,
+ static_cast<uint32_t>(length));
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Let the image know we've sent all the data.
+ rv = image->OnImageDataComplete(nullptr, NS_OK, true);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
+ tracker->SyncNotifyProgress(FLAG_LOAD_COMPLETE);
+
+ // Use GetFrame() to force a sync decode of the image.
+ RefPtr<SourceSurface> surface = image->GetFrame(
+ imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE);
+
+ // Ensure that the image's metadata meets our expectations.
+ IntSize imageSize(0, 0);
+ rv = image->GetWidth(&imageSize.width);
+ EXPECT_NS_SUCCEEDED(rv);
+ rv = image->GetHeight(&imageSize.height);
+ EXPECT_NS_SUCCEEDED(rv);
+
+ EXPECT_EQ(testCase.mSize.width, imageSize.width);
+ EXPECT_EQ(testCase.mSize.height, imageSize.height);
+
+ nsTArray<IntSize> nativeSizes;
+ rv = image->GetNativeSizes(nativeSizes);
+ EXPECT_NS_SUCCEEDED(rv);
+ ASSERT_EQ(6u, nativeSizes.Length());
+
+ IntSize expectedSizes[] = {IntSize(16, 16), IntSize(32, 32),
+ IntSize(64, 64), IntSize(128, 128),
+ IntSize(256, 256), IntSize(256, 128)};
+
+ for (int i = 0; i < 6; ++i) {
+ EXPECT_EQ(expectedSizes[i], nativeSizes[i]);
+ }
+
+ RefPtr<Image> image90 =
+ ImageOps::Orient(image, Orientation(Angle::D90, Flip::Unflipped));
+ rv = image90->GetNativeSizes(nativeSizes);
+ EXPECT_NS_SUCCEEDED(rv);
+ ASSERT_EQ(6u, nativeSizes.Length());
+
+ for (int i = 0; i < 5; ++i) {
+ EXPECT_EQ(expectedSizes[i], nativeSizes[i]);
+ }
+ EXPECT_EQ(IntSize(128, 256), nativeSizes[5]);
+
+ RefPtr<Image> image180 =
+ ImageOps::Orient(image, Orientation(Angle::D180, Flip::Unflipped));
+ rv = image180->GetNativeSizes(nativeSizes);
+ EXPECT_NS_SUCCEEDED(rv);
+ ASSERT_EQ(6u, nativeSizes.Length());
+
+ for (int i = 0; i < 6; ++i) {
+ EXPECT_EQ(expectedSizes[i], nativeSizes[i]);
+ }
+}
+
+TEST_F(ImageDecoders, ExifResolutionEven) {
+ RefPtr<Image> image = TestCaseToDecodedImage(ExifResolutionTestCase());
+ EXPECT_EQ(image->GetResolution(), Resolution(2.0, 2.0));
+}
diff --git a/image/test/gtest/TestDecodersPerf.cpp b/image/test/gtest/TestDecodersPerf.cpp
new file mode 100644
index 0000000000..e1d6bfbded
--- /dev/null
+++ b/image/test/gtest/TestDecodersPerf.cpp
@@ -0,0 +1,159 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+#include "gtest/MozGTestBench.h"
+
+#include "Common.h"
+#include "Decoder.h"
+#include "DecoderFactory.h"
+#include "IDecodingTask.h"
+#include "mozilla/RefPtr.h"
+#include "ProgressTracker.h"
+#include "SourceBuffer.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+namespace {
+
+static void CheckDecoderState(const ImageTestCase& aTestCase,
+ image::Decoder* aDecoder,
+ const IntSize& aOutputSize) {
+ // image::Decoder should match what we asked for in the MIME type.
+ EXPECT_NE(aDecoder->GetType(), DecoderType::UNKNOWN);
+ EXPECT_EQ(aDecoder->GetType(),
+ DecoderFactory::GetDecoderType(aTestCase.mMimeType));
+
+ EXPECT_TRUE(aDecoder->GetDecodeDone());
+ EXPECT_FALSE(aDecoder->HasError());
+
+ // Verify that the decoder made the expected progress.
+ Progress progress = aDecoder->TakeProgress();
+ EXPECT_FALSE(bool(progress & FLAG_HAS_ERROR));
+ EXPECT_FALSE(bool(aTestCase.mFlags & TEST_CASE_HAS_ERROR));
+
+ EXPECT_TRUE(bool(progress & FLAG_SIZE_AVAILABLE));
+ EXPECT_TRUE(bool(progress & FLAG_DECODE_COMPLETE));
+ EXPECT_TRUE(bool(progress & FLAG_FRAME_COMPLETE));
+ EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_TRANSPARENT),
+ bool(progress & FLAG_HAS_TRANSPARENCY));
+ EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_ANIMATED),
+ bool(progress & FLAG_IS_ANIMATED));
+
+ // The decoder should get the correct size.
+ OrientedIntSize size = aDecoder->Size();
+ EXPECT_EQ(aTestCase.mSize.width, size.width);
+ EXPECT_EQ(aTestCase.mSize.height, size.height);
+
+ // Get the current frame, which is always the first frame of the image
+ // because CreateAnonymousDecoder() forces a first-frame-only decode.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+
+ // Verify that the resulting surfaces matches our expectations.
+ EXPECT_TRUE(surface->IsDataSourceSurface());
+ EXPECT_TRUE(surface->GetFormat() == SurfaceFormat::OS_RGBX ||
+ surface->GetFormat() == SurfaceFormat::OS_RGBA);
+ EXPECT_EQ(aOutputSize, surface->GetSize());
+}
+
+template <typename Func>
+static void WithSingleChunkDecode(const ImageTestCase& aTestCase,
+ SourceBuffer* aSourceBuffer,
+ const Maybe<IntSize>& aOutputSize,
+ Func aResultChecker) {
+ auto sourceBuffer = WrapNotNull(RefPtr<SourceBuffer>(aSourceBuffer));
+
+ // Create a decoder.
+ DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType);
+ RefPtr<image::Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(
+ decoderType, sourceBuffer, aOutputSize, DecoderFlags::FIRST_FRAME_ONLY,
+ aTestCase.mSurfaceFlags);
+ ASSERT_TRUE(decoder != nullptr);
+ RefPtr<IDecodingTask> task =
+ new AnonymousDecodingTask(WrapNotNull(decoder), /* aResumable */ false);
+
+ // Run the full decoder synchronously.
+ task->Run();
+
+ // Call the lambda to verify the expected results.
+ aResultChecker(decoder);
+}
+
+static void CheckDecode(const ImageTestCase& aTestCase,
+ SourceBuffer* aSourceBuffer) {
+ WithSingleChunkDecode(
+ aTestCase, aSourceBuffer, Nothing(), [&](image::Decoder* aDecoder) {
+ CheckDecoderState(aTestCase, aDecoder, aTestCase.mSize);
+ });
+}
+
+static void CheckDownscaleDuringDecode(const ImageTestCase& aTestCase,
+ SourceBuffer* aSourceBuffer) {
+ IntSize outputSize(20, 20);
+ WithSingleChunkDecode(aTestCase, aSourceBuffer, Some(outputSize),
+ [&](image::Decoder* aDecoder) {
+ CheckDecoderState(aTestCase, aDecoder, outputSize);
+ });
+}
+
+#define IMAGE_GTEST_BENCH_FIXTURE(test_fixture, test_case) \
+ class test_fixture : public ImageBenchmarkBase { \
+ protected: \
+ test_fixture() : ImageBenchmarkBase(test_case()) {} \
+ };
+
+#define IMAGE_GTEST_NATIVE_BENCH_F(test_fixture) \
+ MOZ_GTEST_BENCH_F(test_fixture, Native, \
+ [this] { CheckDecode(mTestCase, mSourceBuffer); });
+
+#define IMAGE_GTEST_DOWNSCALE_BENCH_F(test_fixture) \
+ MOZ_GTEST_BENCH_F(test_fixture, Downscale, [this] { \
+ CheckDownscaleDuringDecode(mTestCase, mSourceBuffer); \
+ });
+
+#define IMAGE_GTEST_NO_COLOR_MANAGEMENT_BENCH_F(test_fixture) \
+ MOZ_GTEST_BENCH_F(test_fixture, NoColorManagement, [this] { \
+ ImageTestCase testCase = mTestCase; \
+ testCase.mSurfaceFlags |= SurfaceFlags::NO_COLORSPACE_CONVERSION; \
+ CheckDecode(testCase, mSourceBuffer); \
+ });
+
+#define IMAGE_GTEST_NO_PREMULTIPLY_BENCH_F(test_fixture) \
+ MOZ_GTEST_BENCH_F(test_fixture, NoPremultiplyAlpha, [this] { \
+ ImageTestCase testCase = mTestCase; \
+ testCase.mSurfaceFlags |= SurfaceFlags::NO_PREMULTIPLY_ALPHA; \
+ CheckDecode(testCase, mSourceBuffer); \
+ });
+
+#define IMAGE_GTEST_BENCH_F(type, test) \
+ IMAGE_GTEST_BENCH_FIXTURE(ImageDecodersPerf_##type##_##test, \
+ Perf##test##type##TestCase) \
+ IMAGE_GTEST_NATIVE_BENCH_F(ImageDecodersPerf_##type##_##test) \
+ IMAGE_GTEST_DOWNSCALE_BENCH_F(ImageDecodersPerf_##type##_##test) \
+ IMAGE_GTEST_NO_COLOR_MANAGEMENT_BENCH_F(ImageDecodersPerf_##type##_##test)
+
+#define IMAGE_GTEST_BENCH_ALPHA_F(type, test) \
+ IMAGE_GTEST_BENCH_F(type, test) \
+ IMAGE_GTEST_NO_PREMULTIPLY_BENCH_F(ImageDecodersPerf_##type##_##test)
+
+IMAGE_GTEST_BENCH_F(JPG, YCbCr)
+IMAGE_GTEST_BENCH_F(JPG, Cmyk)
+IMAGE_GTEST_BENCH_F(JPG, Gray)
+
+IMAGE_GTEST_BENCH_F(PNG, Rgb)
+IMAGE_GTEST_BENCH_F(PNG, Gray)
+IMAGE_GTEST_BENCH_ALPHA_F(PNG, RgbAlpha)
+IMAGE_GTEST_BENCH_ALPHA_F(PNG, GrayAlpha)
+
+IMAGE_GTEST_BENCH_F(WebP, RgbLossless)
+IMAGE_GTEST_BENCH_F(WebP, RgbLossy)
+IMAGE_GTEST_BENCH_ALPHA_F(WebP, RgbAlphaLossless)
+IMAGE_GTEST_BENCH_ALPHA_F(WebP, RgbAlphaLossy)
+
+IMAGE_GTEST_BENCH_F(GIF, Rgb)
+
+} // namespace
diff --git a/image/test/gtest/TestDeinterlacingFilter.cpp b/image/test/gtest/TestDeinterlacingFilter.cpp
new file mode 100644
index 0000000000..fc3e6f65bd
--- /dev/null
+++ b/image/test/gtest/TestDeinterlacingFilter.cpp
@@ -0,0 +1,636 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "mozilla/gfx/2D.h"
+#include "Common.h"
+#include "Decoder.h"
+#include "DecoderFactory.h"
+#include "SourceBuffer.h"
+#include "SurfaceFilters.h"
+#include "SurfacePipe.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+template <typename Func>
+void WithDeinterlacingFilter(const IntSize& aSize, bool aProgressiveDisplay,
+ Func aFunc) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(bool(decoder));
+
+ WithFilterPipeline(
+ decoder, std::forward<Func>(aFunc),
+ DeinterlacingConfig<uint32_t>{aProgressiveDisplay},
+ SurfaceConfig{decoder, aSize, SurfaceFormat::OS_RGBA, false});
+}
+
+void AssertConfiguringDeinterlacingFilterFails(const IntSize& aSize) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ AssertConfiguringPipelineFails(
+ decoder, DeinterlacingConfig<uint32_t>{/* mProgressiveDisplay = */ true},
+ SurfaceConfig{decoder, aSize, SurfaceFormat::OS_RGBA, false});
+}
+
+class ImageDeinterlacingFilter : public ::testing::Test {
+ protected:
+ AutoInitializeImageLib mInit;
+};
+
+TEST_F(ImageDeinterlacingFilter, WritePixels100_100) {
+ WithDeinterlacingFilter(
+ IntSize(100, 100), /* aProgressiveDisplay = */ true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)));
+ });
+}
+
+TEST_F(ImageDeinterlacingFilter, WritePixels99_99) {
+ WithDeinterlacingFilter(IntSize(99, 99), /* aProgressiveDisplay = */ true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 99, 99)),
+ /* aInputRect = */ Some(IntRect(0, 0, 99, 99)));
+ });
+}
+
+TEST_F(ImageDeinterlacingFilter, WritePixels8_8) {
+ WithDeinterlacingFilter(IntSize(8, 8), /* aProgressiveDisplay = */ true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 8, 8)),
+ /* aInputRect = */ Some(IntRect(0, 0, 8, 8)));
+ });
+}
+
+TEST_F(ImageDeinterlacingFilter, WritePixels7_7) {
+ WithDeinterlacingFilter(IntSize(7, 7), /* aProgressiveDisplay = */ true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 7, 7)),
+ /* aInputRect = */ Some(IntRect(0, 0, 7, 7)));
+ });
+}
+
+TEST_F(ImageDeinterlacingFilter, WritePixels3_3) {
+ WithDeinterlacingFilter(IntSize(3, 3), /* aProgressiveDisplay = */ true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 3, 3)),
+ /* aInputRect = */ Some(IntRect(0, 0, 3, 3)));
+ });
+}
+
+TEST_F(ImageDeinterlacingFilter, WritePixels1_1) {
+ WithDeinterlacingFilter(IntSize(1, 1), /* aProgressiveDisplay = */ true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 1, 1)),
+ /* aInputRect = */ Some(IntRect(0, 0, 1, 1)));
+ });
+}
+
+TEST_F(ImageDeinterlacingFilter, WritePixelsNonProgressiveOutput51_52) {
+ WithDeinterlacingFilter(
+ IntSize(51, 52), /* aProgressiveDisplay = */ false,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Fill the image. The output should be green for even rows and red for
+ // odd rows but we need to write the rows in the order that the
+ // deinterlacer expects them.
+ uint32_t count = 0;
+ auto result = aFilter->WritePixels<uint32_t>([&]() {
+ uint32_t row = count / 51; // Integer division.
+ ++count;
+
+ // Note that we use a switch statement here, even though it's quite
+ // verbose, because it's useful to have the mappings between input and
+ // output rows available when debugging these tests.
+
+ switch (row) {
+ // First pass. Output rows are positioned at 8n + 0.
+ case 0: // Output row 0.
+ case 1: // Output row 8.
+ case 2: // Output row 16.
+ case 3: // Output row 24.
+ case 4: // Output row 32.
+ case 5: // Output row 40.
+ case 6: // Output row 48.
+ return AsVariant(BGRAColor::Green().AsPixel());
+
+ // Second pass. Rows are positioned at 8n + 4.
+ case 7: // Output row 4.
+ case 8: // Output row 12.
+ case 9: // Output row 20.
+ case 10: // Output row 28.
+ case 11: // Output row 36.
+ case 12: // Output row 44.
+ return AsVariant(BGRAColor::Green().AsPixel());
+
+ // Third pass. Rows are positioned at 4n + 2.
+ case 13: // Output row 2.
+ case 14: // Output row 6.
+ case 15: // Output row 10.
+ case 16: // Output row 14.
+ case 17: // Output row 18.
+ case 18: // Output row 22.
+ case 19: // Output row 26.
+ case 20: // Output row 30.
+ case 21: // Output row 34.
+ case 22: // Output row 38.
+ case 23: // Output row 42.
+ case 24: // Output row 46.
+ case 25: // Output row 50.
+ return AsVariant(BGRAColor::Green().AsPixel());
+
+ // Fourth pass. Rows are positioned at 2n + 1.
+ case 26: // Output row 1.
+ case 27: // Output row 3.
+ case 28: // Output row 5.
+ case 29: // Output row 7.
+ case 30: // Output row 9.
+ case 31: // Output row 11.
+ case 32: // Output row 13.
+ case 33: // Output row 15.
+ case 34: // Output row 17.
+ case 35: // Output row 19.
+ case 36: // Output row 21.
+ case 37: // Output row 23.
+ case 38: // Output row 25.
+ case 39: // Output row 27.
+ case 40: // Output row 29.
+ case 41: // Output row 31.
+ case 42: // Output row 33.
+ case 43: // Output row 35.
+ case 44: // Output row 37.
+ case 45: // Output row 39.
+ case 46: // Output row 41.
+ case 47: // Output row 43.
+ case 48: // Output row 45.
+ case 49: // Output row 47.
+ case 50: // Output row 49.
+ case 51: // Output row 51.
+ return AsVariant(BGRAColor::Red().AsPixel());
+
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unexpected row");
+ return AsVariant(BGRAColor::Transparent().AsPixel());
+ }
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(51u * 52u, count);
+
+ AssertCorrectPipelineFinalState(aFilter, IntRect(0, 0, 51, 52),
+ IntRect(0, 0, 51, 52));
+
+ // Check that the generated image is correct. As mentioned above, we
+ // expect even rows to be green and odd rows to be red.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+
+ for (uint32_t row = 0; row < 52; ++row) {
+ EXPECT_TRUE(RowsAreSolidColor(
+ surface, row, 1,
+ row % 2 == 0 ? BGRAColor::Green() : BGRAColor::Red()));
+ }
+ });
+}
+
+TEST_F(ImageDeinterlacingFilter, WritePixelsOutput20_20) {
+ WithDeinterlacingFilter(
+ IntSize(20, 20), /* aProgressiveDisplay = */ true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Fill the image. The output should be green for even rows and red for
+ // odd rows but we need to write the rows in the order that the
+ // deinterlacer expects them.
+ uint32_t count = 0;
+ auto result = aFilter->WritePixels<uint32_t>([&]() {
+ uint32_t row = count / 20; // Integer division.
+ ++count;
+
+ // Note that we use a switch statement here, even though it's quite
+ // verbose, because it's useful to have the mappings between input and
+ // output rows available when debugging these tests.
+
+ switch (row) {
+ // First pass. Output rows are positioned at 8n + 0.
+ case 0: // Output row 0.
+ case 1: // Output row 8.
+ case 2: // Output row 16.
+ return AsVariant(BGRAColor::Green().AsPixel());
+
+ // Second pass. Rows are positioned at 8n + 4.
+ case 3: // Output row 4.
+ case 4: // Output row 12.
+ return AsVariant(BGRAColor::Green().AsPixel());
+
+ // Third pass. Rows are positioned at 4n + 2.
+ case 5: // Output row 2.
+ case 6: // Output row 6.
+ case 7: // Output row 10.
+ case 8: // Output row 14.
+ case 9: // Output row 18.
+ return AsVariant(BGRAColor::Green().AsPixel());
+
+ // Fourth pass. Rows are positioned at 2n + 1.
+ case 10: // Output row 1.
+ case 11: // Output row 3.
+ case 12: // Output row 5.
+ case 13: // Output row 7.
+ case 14: // Output row 9.
+ case 15: // Output row 11.
+ case 16: // Output row 13.
+ case 17: // Output row 15.
+ case 18: // Output row 17.
+ case 19: // Output row 19.
+ return AsVariant(BGRAColor::Red().AsPixel());
+
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unexpected row");
+ return AsVariant(BGRAColor::Transparent().AsPixel());
+ }
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(20u * 20u, count);
+
+ AssertCorrectPipelineFinalState(aFilter, IntRect(0, 0, 20, 20),
+ IntRect(0, 0, 20, 20));
+
+ // Check that the generated image is correct. As mentioned above, we
+ // expect even rows to be green and odd rows to be red.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+
+ for (uint32_t row = 0; row < 20; ++row) {
+ EXPECT_TRUE(RowsAreSolidColor(
+ surface, row, 1,
+ row % 2 == 0 ? BGRAColor::Green() : BGRAColor::Red()));
+ }
+ });
+}
+
+TEST_F(ImageDeinterlacingFilter, WritePixelsOutput7_7) {
+ WithDeinterlacingFilter(
+ IntSize(7, 7), /* aProgressiveDisplay = */ true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Fill the image. The output should be a repeating pattern of two green
+ // rows followed by two red rows but we need to write the rows in the
+ // order that the deinterlacer expects them.
+ uint32_t count = 0;
+ auto result = aFilter->WritePixels<uint32_t>([&]() {
+ uint32_t row = count / 7; // Integer division.
+ ++count;
+
+ switch (row) {
+ // First pass. Output rows are positioned at 8n + 0.
+ case 0: // Output row 0.
+ return AsVariant(BGRAColor::Green().AsPixel());
+
+ // Second pass. Rows are positioned at 8n + 4.
+ case 1: // Output row 4.
+ return AsVariant(BGRAColor::Green().AsPixel());
+
+ // Third pass. Rows are positioned at 4n + 2.
+ case 2: // Output row 2.
+ case 3: // Output row 6.
+ return AsVariant(BGRAColor::Red().AsPixel());
+
+ // Fourth pass. Rows are positioned at 2n + 1.
+ case 4: // Output row 1.
+ return AsVariant(BGRAColor::Green().AsPixel());
+
+ case 5: // Output row 3.
+ return AsVariant(BGRAColor::Red().AsPixel());
+
+ case 6: // Output row 5.
+ return AsVariant(BGRAColor::Green().AsPixel());
+
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unexpected row");
+ return AsVariant(BGRAColor::Transparent().AsPixel());
+ }
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(7u * 7u, count);
+
+ AssertCorrectPipelineFinalState(aFilter, IntRect(0, 0, 7, 7),
+ IntRect(0, 0, 7, 7));
+
+ // Check that the generated image is correct. As mentioned above, we
+ // expect two green rows, followed by two red rows, then two green rows,
+ // etc.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+
+ for (uint32_t row = 0; row < 7; ++row) {
+ BGRAColor color = row == 0 || row == 1 || row == 4 || row == 5
+ ? BGRAColor::Green()
+ : BGRAColor::Red();
+ EXPECT_TRUE(RowsAreSolidColor(surface, row, 1, color));
+ }
+ });
+}
+
+TEST_F(ImageDeinterlacingFilter, WritePixelsOutput3_3) {
+ WithDeinterlacingFilter(
+ IntSize(3, 3), /* aProgressiveDisplay = */ true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Fill the image. The output should be green, red, green in that order,
+ // but we need to write the rows in the order that the deinterlacer
+ // expects them.
+ uint32_t count = 0;
+ auto result = aFilter->WritePixels<uint32_t>([&]() {
+ uint32_t row = count / 3; // Integer division.
+ ++count;
+
+ switch (row) {
+ // First pass. Output rows are positioned at 8n + 0.
+ case 0: // Output row 0.
+ return AsVariant(BGRAColor::Green().AsPixel());
+
+ // Second pass. Rows are positioned at 8n + 4.
+ // No rows for this pass.
+
+ // Third pass. Rows are positioned at 4n + 2.
+ case 1: // Output row 2.
+ return AsVariant(BGRAColor::Green().AsPixel());
+
+ // Fourth pass. Rows are positioned at 2n + 1.
+ case 2: // Output row 1.
+ return AsVariant(BGRAColor::Red().AsPixel());
+
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unexpected row");
+ return AsVariant(BGRAColor::Transparent().AsPixel());
+ }
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(3u * 3u, count);
+
+ AssertCorrectPipelineFinalState(aFilter, IntRect(0, 0, 3, 3),
+ IntRect(0, 0, 3, 3));
+
+ // Check that the generated image is correct. As mentioned above, we
+ // expect green, red, green in that order.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+
+ for (uint32_t row = 0; row < 3; ++row) {
+ EXPECT_TRUE(RowsAreSolidColor(
+ surface, row, 1,
+ row == 0 || row == 2 ? BGRAColor::Green() : BGRAColor::Red()));
+ }
+ });
+}
+
+TEST_F(ImageDeinterlacingFilter, WritePixelsOutput1_1) {
+ WithDeinterlacingFilter(
+ IntSize(1, 1), /* aProgressiveDisplay = */ true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Fill the image. The output should be a single red row.
+ uint32_t count = 0;
+ auto result = aFilter->WritePixels<uint32_t>([&]() {
+ ++count;
+ return AsVariant(BGRAColor::Red().AsPixel());
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(1u, count);
+
+ AssertCorrectPipelineFinalState(aFilter, IntRect(0, 0, 1, 1),
+ IntRect(0, 0, 1, 1));
+
+ // Check that the generated image is correct. As mentioned above, we
+ // expect a single red row.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 1, BGRAColor::Red()));
+ });
+}
+
+void WriteRowAndCheckInterlacerOutput(image::Decoder* aDecoder,
+ SurfaceFilter* aFilter, BGRAColor aColor,
+ WriteState aNextState,
+ OrientedIntRect aInvalidRect,
+ uint32_t aFirstHaeberliRow,
+ uint32_t aLastHaeberliRow) {
+ uint32_t count = 0;
+
+ auto result = aFilter->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
+ if (count < 7) {
+ ++count;
+ return AsVariant(aColor.AsPixel());
+ }
+ return AsVariant(WriteState::NEED_MORE_DATA);
+ });
+
+ EXPECT_EQ(aNextState, result);
+ EXPECT_EQ(7u, count);
+
+ // Assert that we got the expected invalidation region.
+ Maybe<SurfaceInvalidRect> invalidRect = aFilter->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isSome());
+ EXPECT_EQ(aInvalidRect, invalidRect->mInputSpaceRect);
+ EXPECT_EQ(aInvalidRect, invalidRect->mOutputSpaceRect);
+
+ // Check that the portion of the image generated so far is correct. The rows
+ // from aFirstHaeberliRow to aLastHaeberliRow should be filled with aColor.
+ // Note that this is not the same as the set of rows in aInvalidRect, because
+ // after writing a row the deinterlacer seeks to the next row to write, which
+ // may involve copying previously-written rows in the buffer to the output
+ // even though they don't change in this pass.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+
+ for (uint32_t row = aFirstHaeberliRow; row <= aLastHaeberliRow; ++row) {
+ EXPECT_TRUE(RowsAreSolidColor(surface, row, 1, aColor));
+ }
+}
+
+TEST_F(ImageDeinterlacingFilter, WritePixelsIntermediateOutput7_7) {
+ WithDeinterlacingFilter(
+ IntSize(7, 7), /* aProgressiveDisplay = */ true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Fill the image. The output should be a repeating pattern of two green
+ // rows followed by two red rows but we need to write the rows in the
+ // order that the deinterlacer expects them.
+
+ // First pass. Output rows are positioned at 8n + 0.
+
+ // Output row 0. The invalid rect is the entire image because this is
+ // the end of the first pass.
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
+ WriteState::NEED_MORE_DATA,
+ OrientedIntRect(0, 0, 7, 7), 0, 4);
+
+ // Second pass. Rows are positioned at 8n + 4.
+
+ // Output row 4. The invalid rect is the entire image because this is
+ // the end of the second pass.
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
+ WriteState::NEED_MORE_DATA,
+ OrientedIntRect(0, 0, 7, 7), 1, 4);
+
+ // Third pass. Rows are positioned at 4n + 2.
+
+ // Output row 2. The invalid rect contains the Haeberli rows for this
+ // output row (rows 2 and 3) as well as the rows that we copy from
+ // previous passes when seeking to the next output row (rows 4 and 5).
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
+ WriteState::NEED_MORE_DATA,
+ OrientedIntRect(0, 2, 7, 4), 2, 3);
+
+ // Output row 6. The invalid rect is the entire image because this is
+ // the end of the third pass.
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
+ WriteState::NEED_MORE_DATA,
+ OrientedIntRect(0, 0, 7, 7), 6, 6);
+
+ // Fourth pass. Rows are positioned at 2n + 1.
+
+ // Output row 1. The invalid rect contains the Haeberli rows for this
+ // output row (just row 1) as well as the rows that we copy from
+ // previous passes when seeking to the next output row (row 2).
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
+ WriteState::NEED_MORE_DATA,
+ OrientedIntRect(0, 1, 7, 2), 1, 1);
+
+ // Output row 3. The invalid rect contains the Haeberli rows for this
+ // output row (just row 3) as well as the rows that we copy from
+ // previous passes when seeking to the next output row (row 4).
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
+ WriteState::NEED_MORE_DATA,
+ OrientedIntRect(0, 3, 7, 2), 3, 3);
+
+ // Output row 5. The invalid rect contains the Haeberli rows for this
+ // output row (just row 5) as well as the rows that we copy from
+ // previous passes when seeking to the next output row (row 6).
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
+ WriteState::FINISHED,
+ OrientedIntRect(0, 5, 7, 2), 5, 5);
+
+ // Assert that we're in the expected final state.
+ EXPECT_TRUE(aFilter->IsSurfaceFinished());
+ Maybe<SurfaceInvalidRect> invalidRect = aFilter->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isNothing());
+
+ // Check that the generated image is correct. As mentioned above, we
+ // expect two green rows, followed by two red rows, then two green rows,
+ // etc.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+
+ for (uint32_t row = 0; row < 7; ++row) {
+ BGRAColor color = row == 0 || row == 1 || row == 4 || row == 5
+ ? BGRAColor::Green()
+ : BGRAColor::Red();
+ EXPECT_TRUE(RowsAreSolidColor(surface, row, 1, color));
+ }
+ });
+}
+
+TEST_F(ImageDeinterlacingFilter,
+ WritePixelsNonProgressiveIntermediateOutput7_7) {
+ WithDeinterlacingFilter(
+ IntSize(7, 7), /* aProgressiveDisplay = */ false,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Fill the image. The output should be a repeating pattern of two green
+ // rows followed by two red rows but we need to write the rows in the
+ // order that the deinterlacer expects them.
+
+ // First pass. Output rows are positioned at 8n + 0.
+
+ // Output row 0. The invalid rect is the entire image because this is
+ // the end of the first pass.
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
+ WriteState::NEED_MORE_DATA,
+ OrientedIntRect(0, 0, 7, 7), 0, 0);
+
+ // Second pass. Rows are positioned at 8n + 4.
+
+ // Output row 4. The invalid rect is the entire image because this is
+ // the end of the second pass.
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
+ WriteState::NEED_MORE_DATA,
+ OrientedIntRect(0, 0, 7, 7), 4, 4);
+
+ // Third pass. Rows are positioned at 4n + 2.
+
+ // Output row 2. The invalid rect contains the Haeberli rows for this
+ // output row (rows 2 and 3) as well as the rows that we copy from
+ // previous passes when seeking to the next output row (rows 4 and 5).
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
+ WriteState::NEED_MORE_DATA,
+ OrientedIntRect(0, 2, 7, 4), 2, 2);
+
+ // Output row 6. The invalid rect is the entire image because this is
+ // the end of the third pass.
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
+ WriteState::NEED_MORE_DATA,
+ OrientedIntRect(0, 0, 7, 7), 6, 6);
+
+ // Fourth pass. Rows are positioned at 2n + 1.
+
+ // Output row 1. The invalid rect contains the Haeberli rows for this
+ // output row (just row 1) as well as the rows that we copy from
+ // previous passes when seeking to the next output row (row 2).
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
+ WriteState::NEED_MORE_DATA,
+ OrientedIntRect(0, 1, 7, 2), 1, 1);
+
+ // Output row 3. The invalid rect contains the Haeberli rows for this
+ // output row (just row 3) as well as the rows that we copy from
+ // previous passes when seeking to the next output row (row 4).
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
+ WriteState::NEED_MORE_DATA,
+ OrientedIntRect(0, 3, 7, 2), 3, 3);
+
+ // Output row 5. The invalid rect contains the Haeberli rows for this
+ // output row (just row 5) as well as the rows that we copy from
+ // previous passes when seeking to the next output row (row 6).
+ WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
+ WriteState::FINISHED,
+ OrientedIntRect(0, 5, 7, 2), 5, 5);
+
+ // Assert that we're in the expected final state.
+ EXPECT_TRUE(aFilter->IsSurfaceFinished());
+ Maybe<SurfaceInvalidRect> invalidRect = aFilter->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isNothing());
+
+ // Check that the generated image is correct. As mentioned above, we
+ // expect two green rows, followed by two red rows, then two green rows,
+ // etc.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+
+ for (uint32_t row = 0; row < 7; ++row) {
+ BGRAColor color = row == 0 || row == 1 || row == 4 || row == 5
+ ? BGRAColor::Green()
+ : BGRAColor::Red();
+ EXPECT_TRUE(RowsAreSolidColor(surface, row, 1, color));
+ }
+ });
+}
+
+TEST_F(ImageDeinterlacingFilter, DeinterlacingFailsFor0_0) {
+ // A 0x0 input size is invalid, so configuration should fail.
+ AssertConfiguringDeinterlacingFilterFails(IntSize(0, 0));
+}
+
+TEST_F(ImageDeinterlacingFilter, DeinterlacingFailsForMinus1_Minus1) {
+ // A negative input size is invalid, so configuration should fail.
+ AssertConfiguringDeinterlacingFilterFails(IntSize(-1, -1));
+}
diff --git a/image/test/gtest/TestDownscalingFilter.cpp b/image/test/gtest/TestDownscalingFilter.cpp
new file mode 100644
index 0000000000..d00f67d188
--- /dev/null
+++ b/image/test/gtest/TestDownscalingFilter.cpp
@@ -0,0 +1,231 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "mozilla/gfx/2D.h"
+#include "Common.h"
+#include "Decoder.h"
+#include "DecoderFactory.h"
+#include "SourceBuffer.h"
+#include "SurfaceFilters.h"
+#include "SurfacePipe.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+template <typename Func>
+void WithDownscalingFilter(const IntSize& aInputSize,
+ const IntSize& aOutputSize, Func aFunc) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ WithFilterPipeline(
+ decoder, std::forward<Func>(aFunc),
+ DownscalingConfig{aInputSize, SurfaceFormat::OS_RGBA},
+ SurfaceConfig{decoder, aOutputSize, SurfaceFormat::OS_RGBA, false});
+}
+
+void AssertConfiguringDownscalingFilterFails(const IntSize& aInputSize,
+ const IntSize& aOutputSize) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ AssertConfiguringPipelineFails(
+ decoder, DownscalingConfig{aInputSize, SurfaceFormat::OS_RGBA},
+ SurfaceConfig{decoder, aOutputSize, SurfaceFormat::OS_RGBA, false});
+}
+
+TEST(ImageDownscalingFilter, WritePixels100_100to99_99)
+{
+ WithDownscalingFilter(IntSize(100, 100), IntSize(99, 99),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 99, 99)));
+ });
+}
+
+TEST(ImageDownscalingFilter, WritePixels100_100to33_33)
+{
+ WithDownscalingFilter(IntSize(100, 100), IntSize(33, 33),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 33, 33)));
+ });
+}
+
+TEST(ImageDownscalingFilter, WritePixels100_100to1_1)
+{
+ WithDownscalingFilter(IntSize(100, 100), IntSize(1, 1),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 1, 1)));
+ });
+}
+
+TEST(ImageDownscalingFilter, WritePixels100_100to33_99)
+{
+ WithDownscalingFilter(IntSize(100, 100), IntSize(33, 99),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 33, 99)));
+ });
+}
+
+TEST(ImageDownscalingFilter, WritePixels100_100to99_33)
+{
+ WithDownscalingFilter(IntSize(100, 100), IntSize(99, 33),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 99, 33)));
+ });
+}
+
+TEST(ImageDownscalingFilter, WritePixels100_100to99_1)
+{
+ WithDownscalingFilter(IntSize(100, 100), IntSize(99, 1),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 99, 1)));
+ });
+}
+
+TEST(ImageDownscalingFilter, WritePixels100_100to1_99)
+{
+ WithDownscalingFilter(IntSize(100, 100), IntSize(1, 99),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 1, 99)));
+ });
+}
+
+TEST(ImageDownscalingFilter, DownscalingFailsFor100_100to101_101)
+{
+ // Upscaling is disallowed.
+ AssertConfiguringDownscalingFilterFails(IntSize(100, 100), IntSize(101, 101));
+}
+
+TEST(ImageDownscalingFilter, DownscalingFailsFor100_100to100_100)
+{
+ // "Scaling" to the same size is disallowed.
+ AssertConfiguringDownscalingFilterFails(IntSize(100, 100), IntSize(100, 100));
+}
+
+TEST(ImageDownscalingFilter, DownscalingFailsFor0_0toMinus1_Minus1)
+{
+ // A 0x0 input size is disallowed.
+ AssertConfiguringDownscalingFilterFails(IntSize(0, 0), IntSize(-1, -1));
+}
+
+TEST(ImageDownscalingFilter, DownscalingFailsForMinus1_Minus1toMinus2_Minus2)
+{
+ // A negative input size is disallowed.
+ AssertConfiguringDownscalingFilterFails(IntSize(-1, -1), IntSize(-2, -2));
+}
+
+TEST(ImageDownscalingFilter, DownscalingFailsFor100_100to0_0)
+{
+ // A 0x0 output size is disallowed.
+ AssertConfiguringDownscalingFilterFails(IntSize(100, 100), IntSize(0, 0));
+}
+
+TEST(ImageDownscalingFilter, DownscalingFailsFor100_100toMinus1_Minus1)
+{
+ // A negative output size is disallowed.
+ AssertConfiguringDownscalingFilterFails(IntSize(100, 100), IntSize(-1, -1));
+}
+
+TEST(ImageDownscalingFilter, WritePixelsOutput100_100to20_20)
+{
+ WithDownscalingFilter(
+ IntSize(100, 100), IntSize(20, 20),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Fill the image. It consists of 25 lines of green, followed by 25
+ // lines of red, followed by 25 lines of green, followed by 25 more
+ // lines of red.
+ uint32_t count = 0;
+ auto result =
+ aFilter->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
+ uint32_t color =
+ (count <= 25 * 100) || (count > 50 * 100 && count <= 75 * 100)
+ ? BGRAColor::Green().AsPixel()
+ : BGRAColor::Red().AsPixel();
+ ++count;
+ return AsVariant(color);
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u * 100u, count);
+
+ AssertCorrectPipelineFinalState(aFilter, IntRect(0, 0, 100, 100),
+ IntRect(0, 0, 20, 20));
+
+ // Check that the generated image is correct. Note that we skip rows
+ // near the transitions between colors, since the downscaler does not
+ // produce a sharp boundary at these points. Even some of the rows we
+ // test need a small amount of fuzz; this is just the nature of Lanczos
+ // downscaling.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 4, BGRAColor::Green(),
+ /* aFuzz = */ 2));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 6, 3, BGRAColor::Red(),
+ /* aFuzz = */ 3));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 11, 3, BGRAColor::Green(),
+ /* aFuzz = */ 3));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 16, 4, BGRAColor::Red(),
+ /* aFuzz = */ 3));
+ });
+}
+
+TEST(ImageDownscalingFilter, WritePixelsOutput100_100to10_20)
+{
+ WithDownscalingFilter(
+ IntSize(100, 100), IntSize(10, 20),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Fill the image. It consists of 25 lines of green, followed by 25
+ // lines of red, followed by 25 lines of green, followed by 25 more
+ // lines of red.
+ uint32_t count = 0;
+ auto result =
+ aFilter->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
+ uint32_t color =
+ (count <= 25 * 100) || (count > 50 * 100 && count <= 75 * 100)
+ ? BGRAColor::Green().AsPixel()
+ : BGRAColor::Red().AsPixel();
+ ++count;
+ return AsVariant(color);
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u * 100u, count);
+
+ AssertCorrectPipelineFinalState(aFilter, IntRect(0, 0, 100, 100),
+ IntRect(0, 0, 10, 20));
+
+ // Check that the generated image is correct. Note that we skip rows
+ // near the transitions between colors, since the downscaler does not
+ // produce a sharp boundary at these points. Even some of the rows we
+ // test need a small amount of fuzz; this is just the nature of Lanczos
+ // downscaling.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 4, BGRAColor::Green(),
+ /* aFuzz = */ 2));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 6, 3, BGRAColor::Red(),
+ /* aFuzz = */ 3));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 11, 3, BGRAColor::Green(),
+ /* aFuzz = */ 3));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 16, 4, BGRAColor::Red(),
+ /* aFuzz = */ 3));
+ });
+}
diff --git a/image/test/gtest/TestFrameAnimator.cpp b/image/test/gtest/TestFrameAnimator.cpp
new file mode 100644
index 0000000000..cd23f132f8
--- /dev/null
+++ b/image/test/gtest/TestFrameAnimator.cpp
@@ -0,0 +1,130 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "Common.h"
+#include "AnimationSurfaceProvider.h"
+#include "Decoder.h"
+#include "ImageFactory.h"
+#include "nsIInputStream.h"
+#include "RasterImage.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+static void CheckFrameAnimatorBlendResults(const ImageTestCase& aTestCase,
+ RasterImage* aImage, uint8_t aFuzz) {
+ // Allow the animation to actually begin.
+ aImage->IncrementAnimationConsumers();
+
+ // Initialize for the first frame so we can advance.
+ TimeStamp now = TimeStamp::Now();
+ aImage->RequestRefresh(now);
+ EXPECT_EQ(aImage->GetFrameIndex(imgIContainer::FRAME_CURRENT), 0);
+
+ RefPtr<SourceSurface> surface =
+ aImage->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_NONE);
+ ASSERT_TRUE(surface != nullptr);
+
+ CheckGeneratedSurface(surface, IntRect(0, 0, 50, 50),
+ BGRAColor::Transparent(),
+ aTestCase.ChooseColor(BGRAColor::Red()), aFuzz);
+
+ // Advance to the next/final frame.
+ now = TimeStamp::Now() + TimeDuration::FromMilliseconds(500);
+ aImage->RequestRefresh(now);
+ EXPECT_EQ(aImage->GetFrameIndex(imgIContainer::FRAME_CURRENT), 1);
+
+ surface =
+ aImage->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_NONE);
+ ASSERT_TRUE(surface != nullptr);
+ CheckGeneratedSurface(surface, IntRect(0, 0, 50, 50),
+ aTestCase.ChooseColor(BGRAColor::Green()),
+ aTestCase.ChooseColor(BGRAColor::Red()), aFuzz);
+}
+
+template <typename Func>
+static void WithFrameAnimatorDecode(const ImageTestCase& aTestCase,
+ Func aResultChecker) {
+ // Create an image.
+ RefPtr<Image> image = ImageFactory::CreateAnonymousImage(
+ nsDependentCString(aTestCase.mMimeType));
+ ASSERT_TRUE(!image->HasError());
+
+ NotNull<RefPtr<RasterImage>> rasterImage =
+ WrapNotNull(static_cast<RasterImage*>(image.get()));
+
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
+ ASSERT_TRUE(inputStream != nullptr);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ nsresult rv = inputStream->Available(&length);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Write the data into a SourceBuffer.
+ NotNull<RefPtr<SourceBuffer>> sourceBuffer = WrapNotNull(new SourceBuffer());
+ sourceBuffer->ExpectLength(length);
+ rv = sourceBuffer->AppendFromInputStream(inputStream, length);
+ ASSERT_NS_SUCCEEDED(rv);
+ sourceBuffer->Complete(NS_OK);
+
+ // Create a metadata decoder first, because otherwise RasterImage will get
+ // unhappy about finding out the image is animated during a full decode.
+ DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType);
+ DecoderFlags decoderFlags =
+ DecoderFactory::GetDefaultDecoderFlagsForType(decoderType);
+ RefPtr<IDecodingTask> task = DecoderFactory::CreateMetadataDecoder(
+ decoderType, rasterImage, decoderFlags, sourceBuffer);
+ ASSERT_TRUE(task != nullptr);
+
+ // Run the metadata decoder synchronously.
+ task->Run();
+ task = nullptr;
+
+ // Create an AnimationSurfaceProvider which will manage the decoding process
+ // and make this decoder's output available in the surface cache.
+ SurfaceFlags surfaceFlags = aTestCase.mSurfaceFlags;
+ rv = DecoderFactory::CreateAnimationDecoder(
+ decoderType, rasterImage, sourceBuffer, aTestCase.mSize, decoderFlags,
+ surfaceFlags, 0, getter_AddRefs(task));
+ EXPECT_EQ(rv, NS_OK);
+ ASSERT_TRUE(task != nullptr);
+
+ // Run the full decoder synchronously.
+ task->Run();
+
+ // Call the lambda to verify the expected results.
+ aResultChecker(rasterImage.get());
+}
+
+static void CheckFrameAnimatorBlend(const ImageTestCase& aTestCase,
+ uint8_t aFuzz = 0) {
+ WithFrameAnimatorDecode(aTestCase, [&](RasterImage* aImage) {
+ CheckFrameAnimatorBlendResults(aTestCase, aImage, aFuzz);
+ });
+}
+
+class ImageFrameAnimator : public ::testing::Test {
+ protected:
+ AutoInitializeImageLib mInit;
+};
+
+TEST_F(ImageFrameAnimator, BlendGIFWithFilter) {
+ CheckFrameAnimatorBlend(BlendAnimatedGIFTestCase());
+}
+
+TEST_F(ImageFrameAnimator, BlendPNGWithFilter) {
+ CheckFrameAnimatorBlend(BlendAnimatedPNGTestCase());
+}
+
+TEST_F(ImageFrameAnimator, BlendWebPWithFilter) {
+ CheckFrameAnimatorBlend(BlendAnimatedWebPTestCase());
+}
+
+TEST_F(ImageFrameAnimator, BlendAVIFWithFilter) {
+ CheckFrameAnimatorBlend(BlendAnimatedAVIFTestCase(), 1);
+}
diff --git a/image/test/gtest/TestLoader.cpp b/image/test/gtest/TestLoader.cpp
new file mode 100644
index 0000000000..d18302f37a
--- /dev/null
+++ b/image/test/gtest/TestLoader.cpp
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "Common.h"
+#include "imgLoader.h"
+#include "nsMimeTypes.h"
+#include "nsString.h"
+
+using namespace mozilla;
+using namespace mozilla::image;
+
+static void CheckMimeType(const char* aContents, size_t aLength,
+ const char* aExpected) {
+ nsAutoCString detected;
+ nsresult rv = imgLoader::GetMimeTypeFromContent(aContents, aLength, detected);
+ if (aExpected) {
+ ASSERT_NS_SUCCEEDED(rv);
+ EXPECT_TRUE(detected.EqualsASCII(aExpected));
+ } else {
+ ASSERT_NS_FAILED(rv);
+ EXPECT_TRUE(detected.IsEmpty());
+ }
+}
+
+class ImageLoader : public ::testing::Test {
+ protected:
+ AutoInitializeImageLib mInit;
+};
+
+TEST_F(ImageLoader, DetectGIF) {
+ const char buffer[] = "GIF87a";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_GIF);
+}
+
+TEST_F(ImageLoader, DetectPNG) {
+ const char buffer[] = "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_PNG);
+}
+
+TEST_F(ImageLoader, DetectJPEG) {
+ const char buffer[] = "\xFF\xD8\xFF";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_JPEG);
+}
+
+TEST_F(ImageLoader, DetectART) {
+ const char buffer[] = "\x4A\x47\xFF\xFF\x00";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_ART);
+}
+
+TEST_F(ImageLoader, DetectBMP) {
+ const char buffer[] = "BM";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_BMP);
+}
+
+TEST_F(ImageLoader, DetectICO) {
+ const char buffer[] = "\x00\x00\x01\x00";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_ICO);
+}
+
+TEST_F(ImageLoader, DetectWebP) {
+ const char buffer[] = "RIFF\xFF\xFF\xFF\xFFWEBPVP8L";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_WEBP);
+}
+
+TEST_F(ImageLoader, DetectAVIFMajorBrand) {
+ const char buffer[] =
+ "\x00\x00\x00\x20" // box length
+ "ftyp" // box type
+ "avif" // major brand
+ "\x00\x00\x00\x00" // minor version
+ "avifmif1miafMA1B"; // compatible brands
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_AVIF);
+}
+
+TEST_F(ImageLoader, DetectAVIFCompatibleBrand) {
+ const char buffer[] =
+ "\x00\x00\x00\x20" // box length
+ "ftyp" // box type
+ "XXXX" // major brand
+ "\x00\x00\x00\x00" // minor version
+ "avifmif1miafMA1B"; // compatible brands
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_AVIF);
+}
+
+#ifdef MOZ_JXL
+TEST_F(ImageLoader, DetectJXLCodestream) {
+ const char buffer[] = "\xff\x0a";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_JXL);
+}
+
+TEST_F(ImageLoader, DetectJXLContainer) {
+ const char buffer[] =
+ "\x00\x00\x00\x0c"
+ "JXL "
+ "\x0d\x0a\x87\x0a";
+ CheckMimeType(buffer, sizeof(buffer), IMAGE_JXL);
+}
+#endif
+
+TEST_F(ImageLoader, DetectNonImageMP4) {
+ const char buffer[] =
+ "\x00\x00\x00\x1c" // box length
+ "ftyp" // box type
+ "isom" // major brand
+ "\x00\x00\x02\x00" // minor version
+ "isomiso2mp41"; // compatible brands
+ CheckMimeType(buffer, sizeof(buffer), nullptr);
+}
+
+TEST_F(ImageLoader, DetectNone) {
+ const char buffer[] = "abcdefghijklmnop";
+ CheckMimeType(buffer, sizeof(buffer), nullptr);
+}
diff --git a/image/test/gtest/TestMetadata.cpp b/image/test/gtest/TestMetadata.cpp
new file mode 100644
index 0000000000..d230bf42b9
--- /dev/null
+++ b/image/test/gtest/TestMetadata.cpp
@@ -0,0 +1,260 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "Common.h"
+#include "Decoder.h"
+#include "DecoderFactory.h"
+#include "decoders/nsBMPDecoder.h"
+#include "IDecodingTask.h"
+#include "imgIContainer.h"
+#include "ImageFactory.h"
+#include "mozilla/gfx/2D.h"
+#include "nsComponentManagerUtils.h"
+#include "nsCOMPtr.h"
+#include "nsIInputStream.h"
+#include "mozilla/RefPtr.h"
+#include "nsStreamUtils.h"
+#include "nsString.h"
+#include "nsThreadUtils.h"
+#include "ProgressTracker.h"
+#include "SourceBuffer.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+enum class BMPWithinICO { NO, YES };
+
+static void CheckMetadata(const ImageTestCase& aTestCase,
+ BMPWithinICO aBMPWithinICO = BMPWithinICO::NO) {
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
+ ASSERT_TRUE(inputStream != nullptr);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ nsresult rv = inputStream->Available(&length);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Write the data into a SourceBuffer.
+ auto sourceBuffer = MakeNotNull<RefPtr<SourceBuffer>>();
+ sourceBuffer->ExpectLength(length);
+ rv = sourceBuffer->AppendFromInputStream(inputStream, length);
+ ASSERT_NS_SUCCEEDED(rv);
+ sourceBuffer->Complete(NS_OK);
+
+ // Create a metadata decoder.
+ DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType);
+ RefPtr<image::Decoder> decoder =
+ DecoderFactory::CreateAnonymousMetadataDecoder(decoderType, sourceBuffer);
+ ASSERT_TRUE(decoder != nullptr);
+ RefPtr<IDecodingTask> task =
+ new AnonymousDecodingTask(WrapNotNull(decoder), /* aResumable */ false);
+
+ if (aBMPWithinICO == BMPWithinICO::YES) {
+ static_cast<nsBMPDecoder*>(decoder.get())->SetIsWithinICO();
+ }
+
+ // Run the metadata decoder synchronously.
+ task->Run();
+
+ // Ensure that the metadata decoder didn't make progress it shouldn't have
+ // (which would indicate that it decoded past the header of the image).
+ Progress metadataProgress = decoder->TakeProgress();
+ EXPECT_TRUE(
+ 0 == (metadataProgress &
+ ~(FLAG_SIZE_AVAILABLE | FLAG_HAS_TRANSPARENCY | FLAG_IS_ANIMATED)));
+
+ // If the test case is corrupt, assert what we can and return early.
+ if (aTestCase.mFlags & TEST_CASE_HAS_ERROR) {
+ EXPECT_TRUE(decoder->GetDecodeDone());
+ EXPECT_TRUE(decoder->HasError());
+ return;
+ }
+
+ EXPECT_TRUE(decoder->GetDecodeDone() && !decoder->HasError());
+
+ // Check that we got the expected metadata.
+ EXPECT_TRUE(metadataProgress & FLAG_SIZE_AVAILABLE);
+
+ OrientedIntSize metadataSize = decoder->Size();
+ EXPECT_EQ(aTestCase.mSize.width, metadataSize.width);
+ if (aBMPWithinICO == BMPWithinICO::YES) {
+ // Half the data is considered to be part of the AND mask if embedded
+ EXPECT_EQ(aTestCase.mSize.height / 2, metadataSize.height);
+ } else {
+ EXPECT_EQ(aTestCase.mSize.height, metadataSize.height);
+ }
+
+ bool expectTransparency =
+ aBMPWithinICO == BMPWithinICO::YES
+ ? true
+ : bool(aTestCase.mFlags & TEST_CASE_IS_TRANSPARENT);
+ EXPECT_EQ(expectTransparency, bool(metadataProgress & FLAG_HAS_TRANSPARENCY));
+
+ EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_ANIMATED),
+ bool(metadataProgress & FLAG_IS_ANIMATED));
+
+ // Create a full decoder, so we can compare the result.
+ decoder = DecoderFactory::CreateAnonymousDecoder(
+ decoderType, sourceBuffer, Nothing(), DecoderFlags::FIRST_FRAME_ONLY,
+ aTestCase.mSurfaceFlags);
+ ASSERT_TRUE(decoder != nullptr);
+ task =
+ new AnonymousDecodingTask(WrapNotNull(decoder), /* aResumable */ false);
+
+ if (aBMPWithinICO == BMPWithinICO::YES) {
+ static_cast<nsBMPDecoder*>(decoder.get())->SetIsWithinICO();
+ }
+
+ // Run the full decoder synchronously.
+ task->Run();
+
+ EXPECT_TRUE(decoder->GetDecodeDone() && !decoder->HasError());
+ Progress fullProgress = decoder->TakeProgress();
+
+ // If the metadata decoder set a progress bit, the full decoder should also
+ // have set the same bit.
+ EXPECT_EQ(fullProgress, metadataProgress | fullProgress);
+
+ // The full decoder and the metadata decoder should agree on the image's size.
+ OrientedIntSize fullSize = decoder->Size();
+ EXPECT_EQ(metadataSize.width, fullSize.width);
+ EXPECT_EQ(metadataSize.height, fullSize.height);
+
+ // We should not discover transparency during the full decode that we didn't
+ // discover during the metadata decode, unless the image is animated.
+ EXPECT_TRUE(!(fullProgress & FLAG_HAS_TRANSPARENCY) ||
+ (metadataProgress & FLAG_HAS_TRANSPARENCY) ||
+ (fullProgress & FLAG_IS_ANIMATED));
+}
+
+class ImageDecoderMetadata : public ::testing::Test {
+ protected:
+ AutoInitializeImageLib mInit;
+};
+
+TEST_F(ImageDecoderMetadata, TransparentAVIF) {
+ CheckMetadata(TransparentAVIFTestCase());
+}
+
+TEST_F(ImageDecoderMetadata, PNG) { CheckMetadata(GreenPNGTestCase()); }
+TEST_F(ImageDecoderMetadata, TransparentPNG) {
+ CheckMetadata(TransparentPNGTestCase());
+}
+TEST_F(ImageDecoderMetadata, GIF) { CheckMetadata(GreenGIFTestCase()); }
+TEST_F(ImageDecoderMetadata, TransparentGIF) {
+ CheckMetadata(TransparentGIFTestCase());
+}
+TEST_F(ImageDecoderMetadata, JPG) { CheckMetadata(GreenJPGTestCase()); }
+TEST_F(ImageDecoderMetadata, BMP) { CheckMetadata(GreenBMPTestCase()); }
+TEST_F(ImageDecoderMetadata, ICO) { CheckMetadata(GreenICOTestCase()); }
+TEST_F(ImageDecoderMetadata, Icon) { CheckMetadata(GreenIconTestCase()); }
+TEST_F(ImageDecoderMetadata, WebP) { CheckMetadata(GreenWebPTestCase()); }
+
+#ifdef MOZ_JXL
+TEST_F(ImageDecoderMetadata, JXL) { CheckMetadata(GreenJXLTestCase()); }
+TEST_F(ImageDecoderMetadata, TransparentJXL) {
+ CheckMetadata(TransparentJXLTestCase());
+}
+#endif
+
+TEST_F(ImageDecoderMetadata, AnimatedGIF) {
+ CheckMetadata(GreenFirstFrameAnimatedGIFTestCase());
+}
+
+TEST_F(ImageDecoderMetadata, AnimatedPNG) {
+ CheckMetadata(GreenFirstFrameAnimatedPNGTestCase());
+}
+
+TEST_F(ImageDecoderMetadata, FirstFramePaddingGIF) {
+ CheckMetadata(FirstFramePaddingGIFTestCase());
+}
+
+TEST_F(ImageDecoderMetadata, TransparentIfWithinICOBMPNotWithinICO) {
+ CheckMetadata(TransparentIfWithinICOBMPTestCase(TEST_CASE_DEFAULT_FLAGS),
+ BMPWithinICO::NO);
+}
+
+TEST_F(ImageDecoderMetadata, TransparentIfWithinICOBMPWithinICO) {
+ CheckMetadata(TransparentIfWithinICOBMPTestCase(TEST_CASE_IS_TRANSPARENT),
+ BMPWithinICO::YES);
+}
+
+TEST_F(ImageDecoderMetadata, RLE4BMP) { CheckMetadata(RLE4BMPTestCase()); }
+TEST_F(ImageDecoderMetadata, RLE8BMP) { CheckMetadata(RLE8BMPTestCase()); }
+
+TEST_F(ImageDecoderMetadata, Corrupt) { CheckMetadata(CorruptTestCase()); }
+
+TEST_F(ImageDecoderMetadata, NoFrameDelayGIF) {
+ CheckMetadata(NoFrameDelayGIFTestCase());
+}
+
+TEST_F(ImageDecoderMetadata, NoFrameDelayGIFFullDecode) {
+ ImageTestCase testCase = NoFrameDelayGIFTestCase();
+
+ // The previous test (NoFrameDelayGIF) verifies that we *don't* detect that
+ // this test case is animated, because it has a zero frame delay for the first
+ // frame. This test verifies that when we do a full decode, we detect the
+ // animation at that point and successfully decode all the frames.
+
+ // Create an image.
+ RefPtr<Image> image = ImageFactory::CreateAnonymousImage(
+ nsDependentCString(testCase.mMimeType));
+ ASSERT_TRUE(!image->HasError());
+
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(testCase.mPath);
+ ASSERT_TRUE(inputStream != nullptr);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ nsresult rv = inputStream->Available(&length);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Write the data into the image.
+ rv = image->OnImageDataAvailable(nullptr, inputStream, 0,
+ static_cast<uint32_t>(length));
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Let the image know we've sent all the data.
+ rv = image->OnImageDataComplete(nullptr, NS_OK, true);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
+ tracker->SyncNotifyProgress(FLAG_LOAD_COMPLETE);
+
+ // Use GetFrame() to force a sync decode of the image.
+ RefPtr<SourceSurface> surface = image->GetFrame(
+ imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE);
+
+ // Ensure that the image's metadata meets our expectations.
+ IntSize imageSize(0, 0);
+ rv = image->GetWidth(&imageSize.width);
+ EXPECT_NS_SUCCEEDED(rv);
+ rv = image->GetHeight(&imageSize.height);
+ EXPECT_NS_SUCCEEDED(rv);
+
+ EXPECT_EQ(testCase.mSize.width, imageSize.width);
+ EXPECT_EQ(testCase.mSize.height, imageSize.height);
+
+ Progress imageProgress = tracker->GetProgress();
+
+ EXPECT_TRUE(bool(imageProgress & FLAG_HAS_TRANSPARENCY) == false);
+ EXPECT_TRUE(bool(imageProgress & FLAG_IS_ANIMATED) == true);
+
+ // Ensure that we decoded both frames of the image.
+ LookupResult result =
+ SurfaceCache::Lookup(ImageKey(image.get()),
+ RasterSurfaceKey(imageSize, testCase.mSurfaceFlags,
+ PlaybackType::eAnimated),
+ /* aMarkUsed = */ true);
+ ASSERT_EQ(MatchType::EXACT, result.Type());
+
+ EXPECT_NS_SUCCEEDED(result.Surface().Seek(0));
+ EXPECT_TRUE(bool(result.Surface()));
+
+ RefPtr<imgFrame> partialFrame = result.Surface().GetFrame(1);
+ EXPECT_TRUE(bool(partialFrame));
+}
diff --git a/image/test/gtest/TestRemoveFrameRectFilter.cpp b/image/test/gtest/TestRemoveFrameRectFilter.cpp
new file mode 100644
index 0000000000..59549f3ddb
--- /dev/null
+++ b/image/test/gtest/TestRemoveFrameRectFilter.cpp
@@ -0,0 +1,311 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "mozilla/gfx/2D.h"
+#include "Common.h"
+#include "Decoder.h"
+#include "DecoderFactory.h"
+#include "SourceBuffer.h"
+#include "SurfaceFilters.h"
+#include "SurfacePipe.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+template <typename Func>
+void WithRemoveFrameRectFilter(const IntSize& aSize, const IntRect& aFrameRect,
+ Func aFunc) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ WithFilterPipeline(
+ decoder, std::forward<Func>(aFunc), RemoveFrameRectConfig{aFrameRect},
+ SurfaceConfig{decoder, aSize, SurfaceFormat::OS_RGBA, false});
+}
+
+void AssertConfiguringRemoveFrameRectFilterFails(const IntSize& aSize,
+ const IntRect& aFrameRect) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ AssertConfiguringPipelineFails(
+ decoder, RemoveFrameRectConfig{aFrameRect},
+ SurfaceConfig{decoder, aSize, SurfaceFormat::OS_RGBA, false});
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_0_0_100_100)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(0, 0, 100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 100, 100)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_0_0_0_0)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(0, 0, 0, 0),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 0, 0)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 0, 0, 0)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_Minus50_50_0_0)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(-50, 50, 0, 0),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 0, 0)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 0, 0, 0)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_50_Minus50_0_0)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(50, -50, 0, 0),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 0, 0)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 0, 0, 0)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_150_50_0_0)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(150, 50, 0, 0),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 0, 0)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 0, 0, 0)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_50_150_0_0)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(50, 150, 0, 0),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 0, 0)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 0, 0, 0)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_200_200_100_100)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(200, 200, 100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Note that aInputRect is zero-size because RemoveFrameRectFilter
+ // ignores trailing rows that don't show up in the output. (Leading rows
+ // unfortunately can't be ignored.)
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 0, 0)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 0, 0, 0)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_Minus200_25_100_100)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(-200, 25, 100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Note that aInputRect is zero-size because RemoveFrameRectFilter
+ // ignores trailing rows that don't show up in the output. (Leading rows
+ // unfortunately can't be ignored.)
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 0, 0)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 0, 0, 0)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_25_Minus200_100_100)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(25, -200, 100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Note that aInputRect is zero-size because RemoveFrameRectFilter
+ // ignores trailing rows that don't show up in the output. (Leading rows
+ // unfortunately can't be ignored.)
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 0, 0)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 0, 0, 0)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_200_25_100_100)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(200, 25, 100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Note that aInputRect is zero-size because RemoveFrameRectFilter
+ // ignores trailing rows that don't show up in the output. (Leading rows
+ // unfortunately can't be ignored.)
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 0, 0)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 0, 0, 0)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_25_200_100_100)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(25, 200, 100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Note that aInputRect is zero-size because RemoveFrameRectFilter
+ // ignores trailing rows that don't show up in the output. (Leading rows
+ // unfortunately can't be ignored.)
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 0, 0)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 0, 0, 0)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter,
+ WritePixels100_100_to_Minus200_Minus200_100_100)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(-200, -200, 100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 0, 0)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 0, 0, 0)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_Minus50_Minus50_100_100)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(-50, -50, 100, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 0, 50, 50)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_Minus50_25_100_50)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(-50, 25, 100, 50),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 100, 50)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 25, 50, 50)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_25_Minus50_50_100)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(25, -50, 50, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 50, 100)),
+ /* aOutputWriteRect = */ Some(IntRect(25, 0, 50, 50)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_50_25_100_50)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(50, 25, 100, 50),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 100, 50)),
+ /* aOutputWriteRect = */ Some(IntRect(50, 25, 50, 50)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, WritePixels100_100_to_25_50_50_100)
+{
+ WithRemoveFrameRectFilter(
+ IntSize(100, 100), IntRect(25, 50, 50, 100),
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ // Note that aInputRect is 50x50 because RemoveFrameRectFilter ignores
+ // trailing rows that don't show up in the output. (Leading rows
+ // unfortunately can't be ignored.)
+ CheckWritePixels(
+ aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 50, 50)),
+ /* aOutputWriteRect = */ Some(IntRect(25, 50, 50, 100)));
+ });
+}
+
+TEST(ImageRemoveFrameRectFilter, RemoveFrameRectFailsFor0_0_to_0_0_100_100)
+{
+ // A zero-size image is disallowed.
+ AssertConfiguringRemoveFrameRectFilterFails(IntSize(0, 0),
+ IntRect(0, 0, 100, 100));
+}
+
+TEST(ImageRemoveFrameRectFilter,
+ RemoveFrameRectFailsForMinus1_Minus1_to_0_0_100_100)
+{
+ // A negative-size image is disallowed.
+ AssertConfiguringRemoveFrameRectFilterFails(IntSize(-1, -1),
+ IntRect(0, 0, 100, 100));
+}
+
+TEST(ImageRemoveFrameRectFilter, RemoveFrameRectFailsFor100_100_to_0_0_0_0)
+{
+ // A zero size frame rect is disallowed.
+ AssertConfiguringRemoveFrameRectFilterFails(IntSize(100, 100),
+ IntRect(0, 0, -1, -1));
+}
+
+TEST(ImageRemoveFrameRectFilter,
+ RemoveFrameRectFailsFor100_100_to_0_0_Minus1_Minus1)
+{
+ // A negative size frame rect is disallowed.
+ AssertConfiguringRemoveFrameRectFilterFails(IntSize(100, 100),
+ IntRect(0, 0, -1, -1));
+}
diff --git a/image/test/gtest/TestSourceBuffer.cpp b/image/test/gtest/TestSourceBuffer.cpp
new file mode 100644
index 0000000000..478ab56610
--- /dev/null
+++ b/image/test/gtest/TestSourceBuffer.cpp
@@ -0,0 +1,822 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <algorithm>
+#include <cstdint>
+#include <utility>
+
+#include "Common.h"
+#include "SourceBuffer.h"
+#include "SurfaceCache.h"
+#include "gtest/gtest.h"
+#include "nsIInputStream.h"
+
+using namespace mozilla;
+using namespace mozilla::image;
+
+using std::min;
+
+void ExpectChunkAndByteCount(const SourceBufferIterator& aIterator,
+ uint32_t aChunks, size_t aBytes) {
+ EXPECT_EQ(aChunks, aIterator.ChunkCount());
+ EXPECT_EQ(aBytes, aIterator.ByteCount());
+}
+
+void ExpectRemainingBytes(const SourceBufferIterator& aIterator,
+ size_t aBytes) {
+ EXPECT_TRUE(aIterator.RemainingBytesIsNoMoreThan(aBytes));
+ EXPECT_TRUE(aIterator.RemainingBytesIsNoMoreThan(aBytes + 1));
+
+ if (aBytes > 0) {
+ EXPECT_FALSE(aIterator.RemainingBytesIsNoMoreThan(0));
+ EXPECT_FALSE(aIterator.RemainingBytesIsNoMoreThan(aBytes - 1));
+ }
+}
+
+char GenerateByte(size_t aIndex) {
+ uint8_t byte = aIndex % 256;
+ return *reinterpret_cast<char*>(&byte);
+}
+
+void GenerateData(char* aOutput, size_t aOffset, size_t aLength) {
+ for (size_t i = 0; i < aLength; ++i) {
+ aOutput[i] = GenerateByte(aOffset + i);
+ }
+}
+
+void GenerateData(char* aOutput, size_t aLength) {
+ GenerateData(aOutput, 0, aLength);
+}
+
+void CheckData(const char* aData, size_t aOffset, size_t aLength) {
+ for (size_t i = 0; i < aLength; ++i) {
+ ASSERT_EQ(GenerateByte(aOffset + i), aData[i]);
+ }
+}
+
+enum class AdvanceMode { eAdvanceAsMuchAsPossible, eAdvanceByLengthExactly };
+
+class ImageSourceBuffer : public ::testing::Test {
+ public:
+ ImageSourceBuffer()
+ : mSourceBuffer(new SourceBuffer),
+ mExpectNoResume(new ExpectNoResume),
+ mCountResumes(new CountResumes) {
+ GenerateData(mData, sizeof(mData));
+ EXPECT_FALSE(mSourceBuffer->IsComplete());
+ }
+
+ protected:
+ void CheckedAppendToBuffer(const char* aData, size_t aLength) {
+ EXPECT_NS_SUCCEEDED(mSourceBuffer->Append(aData, aLength));
+ }
+
+ void CheckedAppendToBufferLastByteForLength(size_t aLength) {
+ const char lastByte = GenerateByte(aLength);
+ CheckedAppendToBuffer(&lastByte, 1);
+ }
+
+ void CheckedAppendToBufferInChunks(size_t aChunkLength, size_t aTotalLength) {
+ char* data = new char[aChunkLength];
+
+ size_t bytesWritten = 0;
+ while (bytesWritten < aTotalLength) {
+ GenerateData(data, bytesWritten, aChunkLength);
+ size_t toWrite = min(aChunkLength, aTotalLength - bytesWritten);
+ CheckedAppendToBuffer(data, toWrite);
+ bytesWritten += toWrite;
+ }
+
+ delete[] data;
+ }
+
+ void CheckedCompleteBuffer(nsresult aCompletionStatus = NS_OK) {
+ mSourceBuffer->Complete(aCompletionStatus);
+ EXPECT_TRUE(mSourceBuffer->IsComplete());
+ }
+
+ void CheckedCompleteBuffer(SourceBufferIterator& aIterator, size_t aLength,
+ nsresult aCompletionStatus = NS_OK) {
+ CheckedCompleteBuffer(aCompletionStatus);
+ ExpectRemainingBytes(aIterator, aLength);
+ }
+
+ void CheckedAdvanceIteratorStateOnly(
+ SourceBufferIterator& aIterator, size_t aLength, uint32_t aChunks,
+ size_t aTotalLength,
+ AdvanceMode aAdvanceMode = AdvanceMode::eAdvanceAsMuchAsPossible) {
+ const size_t advanceBy =
+ aAdvanceMode == AdvanceMode::eAdvanceAsMuchAsPossible ? SIZE_MAX
+ : aLength;
+
+ auto state = aIterator.AdvanceOrScheduleResume(advanceBy, mExpectNoResume);
+ ASSERT_EQ(SourceBufferIterator::READY, state);
+ EXPECT_TRUE(aIterator.Data());
+ EXPECT_EQ(aLength, aIterator.Length());
+
+ ExpectChunkAndByteCount(aIterator, aChunks, aTotalLength);
+ }
+
+ void CheckedAdvanceIteratorStateOnly(SourceBufferIterator& aIterator,
+ size_t aLength) {
+ CheckedAdvanceIteratorStateOnly(aIterator, aLength, 1, aLength);
+ }
+
+ void CheckedAdvanceIterator(
+ SourceBufferIterator& aIterator, size_t aLength, uint32_t aChunks,
+ size_t aTotalLength,
+ AdvanceMode aAdvanceMode = AdvanceMode::eAdvanceAsMuchAsPossible) {
+ // Check that the iterator is in the expected state.
+ CheckedAdvanceIteratorStateOnly(aIterator, aLength, aChunks, aTotalLength,
+ aAdvanceMode);
+
+ // Check that we read the expected data. To do this, we need to compute our
+ // offset in the SourceBuffer, but fortunately that's pretty easy: it's the
+ // total number of bytes the iterator has advanced through, minus the length
+ // of the current chunk.
+ const size_t offset = aIterator.ByteCount() - aIterator.Length();
+ CheckData(aIterator.Data(), offset, aIterator.Length());
+ }
+
+ void CheckedAdvanceIterator(SourceBufferIterator& aIterator, size_t aLength) {
+ CheckedAdvanceIterator(aIterator, aLength, 1, aLength);
+ }
+
+ void CheckIteratorMustWait(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) {
+ auto state = aIterator.AdvanceOrScheduleResume(1, aOnResume);
+ EXPECT_EQ(SourceBufferIterator::WAITING, state);
+ }
+
+ void CheckIteratorIsComplete(SourceBufferIterator& aIterator,
+ uint32_t aChunks, size_t aTotalLength,
+ nsresult aCompletionStatus = NS_OK) {
+ ASSERT_TRUE(mSourceBuffer->IsComplete());
+ auto state = aIterator.AdvanceOrScheduleResume(1, mExpectNoResume);
+ ASSERT_EQ(SourceBufferIterator::COMPLETE, state);
+ EXPECT_EQ(aCompletionStatus, aIterator.CompletionStatus());
+ ExpectRemainingBytes(aIterator, 0);
+ ExpectChunkAndByteCount(aIterator, aChunks, aTotalLength);
+ }
+
+ void CheckIteratorIsComplete(SourceBufferIterator& aIterator,
+ size_t aTotalLength) {
+ CheckIteratorIsComplete(aIterator, 1, aTotalLength);
+ }
+
+ AutoInitializeImageLib mInit;
+ char mData[9];
+ RefPtr<SourceBuffer> mSourceBuffer;
+ RefPtr<ExpectNoResume> mExpectNoResume;
+ RefPtr<CountResumes> mCountResumes;
+};
+
+TEST_F(ImageSourceBuffer, InitialState) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // RemainingBytesIsNoMoreThan() should always return false in the initial
+ // state, since we can't know the answer until Complete() has been called.
+ EXPECT_FALSE(iterator.RemainingBytesIsNoMoreThan(0));
+ EXPECT_FALSE(iterator.RemainingBytesIsNoMoreThan(SIZE_MAX));
+
+ // We haven't advanced our iterator at all, so its counters should be zero.
+ ExpectChunkAndByteCount(iterator, 0, 0);
+
+ // Attempt to advance; we should fail, and end up in the WAITING state. We
+ // expect no resumes because we don't actually append anything to the
+ // SourceBuffer in this test.
+ CheckIteratorMustWait(iterator, mExpectNoResume);
+}
+
+TEST_F(ImageSourceBuffer, ZeroLengthBufferAlwaysFails) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Complete the buffer without writing to it, providing a successful
+ // completion status.
+ CheckedCompleteBuffer(iterator, 0);
+
+ // Completing a buffer without writing to it results in an automatic failure;
+ // make sure that the actual completion status we get from the iterator
+ // reflects this.
+ CheckIteratorIsComplete(iterator, 0, 0, NS_ERROR_FAILURE);
+}
+
+TEST_F(ImageSourceBuffer, CompleteSuccess) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Write a single byte to the buffer and complete the buffer. (We have to
+ // write at least one byte because completing a zero length buffer always
+ // fails; see the ZeroLengthBufferAlwaysFails test.)
+ CheckedAppendToBuffer(mData, 1);
+ CheckedCompleteBuffer(iterator, 1);
+
+ // We should be able to advance once (to read the single byte) and then should
+ // reach the COMPLETE state with a successful status.
+ CheckedAdvanceIterator(iterator, 1);
+ CheckIteratorIsComplete(iterator, 1);
+}
+
+TEST_F(ImageSourceBuffer, CompleteFailure) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Write a single byte to the buffer and complete the buffer. (We have to
+ // write at least one byte because completing a zero length buffer always
+ // fails; see the ZeroLengthBufferAlwaysFails test.)
+ CheckedAppendToBuffer(mData, 1);
+ CheckedCompleteBuffer(iterator, 1, NS_ERROR_FAILURE);
+
+ // Advance the iterator. Because a failing status is propagated to the
+ // iterator as soon as it advances, we won't be able to read the single byte
+ // that we wrote above; we go directly into the COMPLETE state.
+ CheckIteratorIsComplete(iterator, 0, 0, NS_ERROR_FAILURE);
+}
+
+TEST_F(ImageSourceBuffer, Append) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Write test data to the buffer.
+ EXPECT_NS_SUCCEEDED(mSourceBuffer->ExpectLength(sizeof(mData)));
+ CheckedAppendToBuffer(mData, sizeof(mData));
+ CheckedCompleteBuffer(iterator, sizeof(mData));
+
+ // Verify that we can read it back via the iterator, and that the final state
+ // is what we expect.
+ CheckedAdvanceIterator(iterator, sizeof(mData));
+ CheckIteratorIsComplete(iterator, sizeof(mData));
+}
+
+TEST_F(ImageSourceBuffer, HugeAppendFails) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // We should fail to append anything bigger than what the SurfaceCache can
+ // hold, so use the SurfaceCache's maximum capacity to calculate what a
+ // "massive amount of data" (see below) consists of on this platform.
+ ASSERT_LT(SurfaceCache::MaximumCapacity(), SIZE_MAX);
+ const size_t hugeSize = SurfaceCache::MaximumCapacity() + 1;
+
+ // Attempt to write a massive amount of data and verify that it fails. (We'd
+ // get a buffer overrun during the test if it succeeds, but if it succeeds
+ // that's the least of our problems.)
+ EXPECT_NS_FAILED(mSourceBuffer->Append(mData, hugeSize));
+ EXPECT_TRUE(mSourceBuffer->IsComplete());
+ CheckIteratorIsComplete(iterator, 0, 0, NS_ERROR_OUT_OF_MEMORY);
+}
+
+TEST_F(ImageSourceBuffer, AppendFromInputStream) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Construct an input stream with some arbitrary data. (We use test data from
+ // one of the decoder tests.)
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(GreenPNGTestCase().mPath);
+ ASSERT_TRUE(inputStream != nullptr);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ ASSERT_NS_SUCCEEDED(inputStream->Available(&length));
+
+ // Write test data to the buffer.
+ EXPECT_TRUE(
+ NS_SUCCEEDED(mSourceBuffer->AppendFromInputStream(inputStream, length)));
+ CheckedCompleteBuffer(iterator, length);
+
+ // Verify that the iterator sees the appropriate amount of data.
+ CheckedAdvanceIteratorStateOnly(iterator, length);
+ CheckIteratorIsComplete(iterator, length);
+}
+
+TEST_F(ImageSourceBuffer, AppendAfterComplete) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Write test data to the buffer.
+ EXPECT_NS_SUCCEEDED(mSourceBuffer->ExpectLength(sizeof(mData)));
+ CheckedAppendToBuffer(mData, sizeof(mData));
+ CheckedCompleteBuffer(iterator, sizeof(mData));
+
+ // Verify that we can read it back via the iterator, and that the final state
+ // is what we expect.
+ CheckedAdvanceIterator(iterator, sizeof(mData));
+ CheckIteratorIsComplete(iterator, sizeof(mData));
+
+ // Write more data to the completed buffer.
+ EXPECT_NS_FAILED(mSourceBuffer->Append(mData, sizeof(mData)));
+
+ // Try to read with a new iterator and verify that the new data got ignored.
+ SourceBufferIterator iterator2 = mSourceBuffer->Iterator();
+ CheckedAdvanceIterator(iterator2, sizeof(mData));
+ CheckIteratorIsComplete(iterator2, sizeof(mData));
+}
+
+TEST_F(ImageSourceBuffer, MinChunkCapacity) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Write test data to the buffer using many small appends. Since
+ // ExpectLength() isn't being called, we should be able to write up to
+ // SourceBuffer::MIN_CHUNK_CAPACITY bytes without a second chunk being
+ // allocated.
+ CheckedAppendToBufferInChunks(10, SourceBuffer::MIN_CHUNK_CAPACITY);
+
+ // Verify that the iterator sees the appropriate amount of data.
+ CheckedAdvanceIterator(iterator, SourceBuffer::MIN_CHUNK_CAPACITY);
+
+ // Write one more byte; we expect to see that it triggers an allocation.
+ CheckedAppendToBufferLastByteForLength(SourceBuffer::MIN_CHUNK_CAPACITY);
+ CheckedCompleteBuffer(iterator, 1);
+
+ // Verify that the iterator sees the new byte and a new chunk has been
+ // allocated.
+ CheckedAdvanceIterator(iterator, 1, 2, SourceBuffer::MIN_CHUNK_CAPACITY + 1);
+ CheckIteratorIsComplete(iterator, 2, SourceBuffer::MIN_CHUNK_CAPACITY + 1);
+}
+
+TEST_F(ImageSourceBuffer, ExpectLengthAllocatesRequestedCapacity) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Write SourceBuffer::MIN_CHUNK_CAPACITY bytes of test data to the buffer,
+ // but call ExpectLength() first to make SourceBuffer expect only a single
+ // byte. We expect this to still result in two chunks, because we trust the
+ // initial guess of ExpectLength() but after that it will only allocate chunks
+ // of at least MIN_CHUNK_CAPACITY bytes.
+ EXPECT_NS_SUCCEEDED(mSourceBuffer->ExpectLength(1));
+ CheckedAppendToBufferInChunks(10, SourceBuffer::MIN_CHUNK_CAPACITY);
+ CheckedCompleteBuffer(iterator, SourceBuffer::MIN_CHUNK_CAPACITY);
+
+ // Verify that the iterator sees a first chunk with 1 byte, and a second chunk
+ // with the remaining data.
+ CheckedAdvanceIterator(iterator, 1, 1, 1);
+ CheckedAdvanceIterator(iterator, SourceBuffer::MIN_CHUNK_CAPACITY - 1, 2,
+ SourceBuffer::MIN_CHUNK_CAPACITY);
+ CheckIteratorIsComplete(iterator, 2, SourceBuffer::MIN_CHUNK_CAPACITY);
+}
+
+TEST_F(ImageSourceBuffer, ExpectLengthGrowsAboveMinCapacity) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Write two times SourceBuffer::MIN_CHUNK_CAPACITY bytes of test data to the
+ // buffer, calling ExpectLength() with the correct length first. We expect
+ // this to result in only one chunk, because ExpectLength() allows us to
+ // allocate a larger first chunk than MIN_CHUNK_CAPACITY bytes.
+ const size_t length = 2 * SourceBuffer::MIN_CHUNK_CAPACITY;
+ EXPECT_NS_SUCCEEDED(mSourceBuffer->ExpectLength(length));
+ CheckedAppendToBufferInChunks(10, length);
+
+ // Verify that the iterator sees a single chunk.
+ CheckedAdvanceIterator(iterator, length);
+
+ // Write one more byte; we expect to see that it triggers an allocation.
+ CheckedAppendToBufferLastByteForLength(length);
+ CheckedCompleteBuffer(iterator, 1);
+
+ // Verify that the iterator sees the new byte and a new chunk has been
+ // allocated.
+ CheckedAdvanceIterator(iterator, 1, 2, length + 1);
+ CheckIteratorIsComplete(iterator, 2, length + 1);
+}
+
+TEST_F(ImageSourceBuffer, HugeExpectLengthFails) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // ExpectLength() should fail if the length is bigger than what the
+ // SurfaceCache can hold, so use the SurfaceCache's maximum capacity to
+ // calculate what a "massive amount of data" (see below) consists of on this
+ // platform.
+ ASSERT_LT(SurfaceCache::MaximumCapacity(), SIZE_MAX);
+ const size_t hugeSize = SurfaceCache::MaximumCapacity() + 1;
+
+ // Attempt to write a massive amount of data and verify that it fails. (We'd
+ // get a buffer overrun during the test if it succeeds, but if it succeeds
+ // that's the least of our problems.)
+ EXPECT_NS_FAILED(mSourceBuffer->ExpectLength(hugeSize));
+ EXPECT_TRUE(mSourceBuffer->IsComplete());
+ CheckIteratorIsComplete(iterator, 0, 0, NS_ERROR_INVALID_ARG);
+}
+
+TEST_F(ImageSourceBuffer, LargeAppendsAllocateOnlyOneChunk) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Write two times SourceBuffer::MIN_CHUNK_CAPACITY bytes of test data to the
+ // buffer in a single Append() call. We expect this to result in only one
+ // chunk even though ExpectLength() wasn't called, because we should always
+ // allocate a new chunk large enough to store the data we have at hand.
+ constexpr size_t length = 2 * SourceBuffer::MIN_CHUNK_CAPACITY;
+ char data[length];
+ GenerateData(data, sizeof(data));
+ CheckedAppendToBuffer(data, length);
+
+ // Verify that the iterator sees a single chunk.
+ CheckedAdvanceIterator(iterator, length);
+
+ // Write one more byte; we expect to see that it triggers an allocation.
+ CheckedAppendToBufferLastByteForLength(length);
+ CheckedCompleteBuffer(iterator, 1);
+
+ // Verify that the iterator sees the new byte and a new chunk has been
+ // allocated.
+ CheckedAdvanceIterator(iterator, 1, 2, length + 1);
+ CheckIteratorIsComplete(iterator, 2, length + 1);
+}
+
+TEST_F(ImageSourceBuffer, LargeAppendsAllocateAtMostOneChunk) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Allocate some data we'll use below.
+ constexpr size_t firstWriteLength = SourceBuffer::MIN_CHUNK_CAPACITY / 2;
+ constexpr size_t secondWriteLength = 3 * SourceBuffer::MIN_CHUNK_CAPACITY;
+ constexpr size_t totalLength = firstWriteLength + secondWriteLength;
+ char data[totalLength];
+ GenerateData(data, sizeof(data));
+
+ // Write half of SourceBuffer::MIN_CHUNK_CAPACITY bytes of test data to the
+ // buffer in a single Append() call. This should fill half of the first chunk.
+ CheckedAppendToBuffer(data, firstWriteLength);
+
+ // Write three times SourceBuffer::MIN_CHUNK_CAPACITY bytes of test data to
+ // the buffer in a single Append() call. We expect this to result in the first
+ // of the first chunk being filled and a new chunk being allocated for the
+ // remainder.
+ CheckedAppendToBuffer(data + firstWriteLength, secondWriteLength);
+
+ // Verify that the iterator sees a MIN_CHUNK_CAPACITY-length chunk.
+ CheckedAdvanceIterator(iterator, SourceBuffer::MIN_CHUNK_CAPACITY);
+
+ // Verify that the iterator sees a second chunk of the length we expect.
+ const size_t expectedSecondChunkLength =
+ totalLength - SourceBuffer::MIN_CHUNK_CAPACITY;
+ CheckedAdvanceIterator(iterator, expectedSecondChunkLength, 2, totalLength);
+
+ // Write one more byte; we expect to see that it triggers an allocation.
+ CheckedAppendToBufferLastByteForLength(totalLength);
+ CheckedCompleteBuffer(iterator, 1);
+
+ // Verify that the iterator sees the new byte and a new chunk has been
+ // allocated.
+ CheckedAdvanceIterator(iterator, 1, 3, totalLength + 1);
+ CheckIteratorIsComplete(iterator, 3, totalLength + 1);
+}
+
+TEST_F(ImageSourceBuffer, OversizedAppendsAllocateAtMostOneChunk) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Allocate some data we'll use below.
+ constexpr size_t writeLength = SourceBuffer::MAX_CHUNK_CAPACITY + 1;
+
+ // Write SourceBuffer::MAX_CHUNK_CAPACITY + 1 bytes of test data to the
+ // buffer in a single Append() call. This should cause one chunk to be
+ // allocated because we wrote it as a single block.
+ CheckedAppendToBufferInChunks(writeLength, writeLength);
+
+ // Verify that the iterator sees a MAX_CHUNK_CAPACITY+1-length chunk.
+ CheckedAdvanceIterator(iterator, writeLength);
+
+ CheckedCompleteBuffer(NS_OK);
+ CheckIteratorIsComplete(iterator, 1, writeLength);
+}
+
+TEST_F(ImageSourceBuffer, CompactionHappensWhenBufferIsComplete) {
+ constexpr size_t chunkLength = SourceBuffer::MIN_CHUNK_CAPACITY;
+ constexpr size_t totalLength = 2 * chunkLength;
+
+ // Write enough data to create two chunks.
+ CheckedAppendToBufferInChunks(chunkLength, totalLength);
+
+ {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Verify that the iterator sees two chunks.
+ CheckedAdvanceIterator(iterator, chunkLength);
+ CheckedAdvanceIterator(iterator, chunkLength, 2, totalLength);
+ }
+
+ // Complete the buffer, which should trigger compaction implicitly.
+ CheckedCompleteBuffer();
+
+ {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Verify that compaction happened and there's now only one chunk.
+ CheckedAdvanceIterator(iterator, totalLength);
+ CheckIteratorIsComplete(iterator, 1, totalLength);
+ }
+}
+
+TEST_F(ImageSourceBuffer, CompactionIsDelayedWhileIteratorsExist) {
+ constexpr size_t chunkLength = SourceBuffer::MIN_CHUNK_CAPACITY;
+ constexpr size_t totalLength = 2 * chunkLength;
+
+ {
+ SourceBufferIterator outerIterator = mSourceBuffer->Iterator();
+
+ {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Write enough data to create two chunks.
+ CheckedAppendToBufferInChunks(chunkLength, totalLength);
+ CheckedCompleteBuffer(iterator, totalLength);
+
+ // Verify that the iterator sees two chunks. Since there are live
+ // iterators, compaction shouldn't have happened when we completed the
+ // buffer.
+ CheckedAdvanceIterator(iterator, chunkLength);
+ CheckedAdvanceIterator(iterator, chunkLength, 2, totalLength);
+ CheckIteratorIsComplete(iterator, 2, totalLength);
+ }
+
+ // Now |iterator| has been destroyed, but |outerIterator| still exists, so
+ // we expect no compaction to have occurred at this point.
+ CheckedAdvanceIterator(outerIterator, chunkLength);
+ CheckedAdvanceIterator(outerIterator, chunkLength, 2, totalLength);
+ CheckIteratorIsComplete(outerIterator, 2, totalLength);
+ }
+
+ // Now all iterators have been destroyed. Since the buffer was already
+ // complete, we expect compaction to happen implicitly here.
+
+ {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Verify that compaction happened and there's now only one chunk.
+ CheckedAdvanceIterator(iterator, totalLength);
+ CheckIteratorIsComplete(iterator, 1, totalLength);
+ }
+}
+
+TEST_F(ImageSourceBuffer, SourceBufferIteratorsCanBeMoved) {
+ constexpr size_t chunkLength = SourceBuffer::MIN_CHUNK_CAPACITY;
+ constexpr size_t totalLength = 2 * chunkLength;
+
+ // Write enough data to create two chunks. We create an iterator here to make
+ // sure that compaction doesn't happen during the test.
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+ CheckedAppendToBufferInChunks(chunkLength, totalLength);
+ CheckedCompleteBuffer(iterator, totalLength);
+
+ auto GetIterator = [&] {
+ SourceBufferIterator lambdaIterator = mSourceBuffer->Iterator();
+ CheckedAdvanceIterator(lambdaIterator, chunkLength);
+ return lambdaIterator;
+ };
+
+ // Move-construct |movedIterator| from the iterator returned from
+ // GetIterator() and check that its state is as we expect.
+ SourceBufferIterator tmpIterator = GetIterator();
+ SourceBufferIterator movedIterator(std::move(tmpIterator));
+ EXPECT_TRUE(movedIterator.Data());
+ EXPECT_EQ(chunkLength, movedIterator.Length());
+ ExpectChunkAndByteCount(movedIterator, 1, chunkLength);
+
+ // Make sure that we can advance the iterator.
+ CheckedAdvanceIterator(movedIterator, chunkLength, 2, totalLength);
+
+ // Make sure that the iterator handles completion properly.
+ CheckIteratorIsComplete(movedIterator, 2, totalLength);
+
+ // Move-assign |movedIterator| from the iterator returned from
+ // GetIterator() and check that its state is as we expect.
+ tmpIterator = GetIterator();
+ movedIterator = std::move(tmpIterator);
+ EXPECT_TRUE(movedIterator.Data());
+ EXPECT_EQ(chunkLength, movedIterator.Length());
+ ExpectChunkAndByteCount(movedIterator, 1, chunkLength);
+
+ // Make sure that we can advance the iterator.
+ CheckedAdvanceIterator(movedIterator, chunkLength, 2, totalLength);
+
+ // Make sure that the iterator handles completion properly.
+ CheckIteratorIsComplete(movedIterator, 2, totalLength);
+}
+
+TEST_F(ImageSourceBuffer, SubchunkAdvance) {
+ constexpr size_t chunkLength = SourceBuffer::MIN_CHUNK_CAPACITY;
+ constexpr size_t totalLength = 2 * chunkLength;
+
+ // Write enough data to create two chunks. We create our iterator here to make
+ // sure that compaction doesn't happen during the test.
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+ CheckedAppendToBufferInChunks(chunkLength, totalLength);
+ CheckedCompleteBuffer(iterator, totalLength);
+
+ // Advance through the first chunk. The chunk count should not increase.
+ // We check that by always passing 1 for the |aChunks| parameter of
+ // CheckedAdvanceIteratorStateOnly(). We have to call CheckData() manually
+ // because the offset calculation in CheckedAdvanceIterator() assumes that
+ // we're advancing a chunk at a time.
+ size_t offset = 0;
+ while (offset < chunkLength) {
+ CheckedAdvanceIteratorStateOnly(iterator, 1, 1, chunkLength,
+ AdvanceMode::eAdvanceByLengthExactly);
+ CheckData(iterator.Data(), offset++, iterator.Length());
+ }
+
+ // Read the first byte of the second chunk. This is the point at which we
+ // can't advance within the same chunk, so the chunk count should increase. We
+ // check that by passing 2 for the |aChunks| parameter of
+ // CheckedAdvanceIteratorStateOnly().
+ CheckedAdvanceIteratorStateOnly(iterator, 1, 2, totalLength,
+ AdvanceMode::eAdvanceByLengthExactly);
+ CheckData(iterator.Data(), offset++, iterator.Length());
+
+ // Read the rest of the second chunk. The chunk count should not increase.
+ while (offset < totalLength) {
+ CheckedAdvanceIteratorStateOnly(iterator, 1, 2, totalLength,
+ AdvanceMode::eAdvanceByLengthExactly);
+ CheckData(iterator.Data(), offset++, iterator.Length());
+ }
+
+ // Make sure we reached the end.
+ CheckIteratorIsComplete(iterator, 2, totalLength);
+}
+
+TEST_F(ImageSourceBuffer, SubchunkZeroByteAdvance) {
+ constexpr size_t chunkLength = SourceBuffer::MIN_CHUNK_CAPACITY;
+ constexpr size_t totalLength = 2 * chunkLength;
+
+ // Write enough data to create two chunks. We create our iterator here to make
+ // sure that compaction doesn't happen during the test.
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+ CheckedAppendToBufferInChunks(chunkLength, totalLength);
+ CheckedCompleteBuffer(iterator, totalLength);
+
+ // Make an initial zero-length advance. Although a zero-length advance
+ // normally won't cause us to read a chunk from the SourceBuffer, we'll do so
+ // if the iterator is in the initial state to keep the invariant that
+ // SourceBufferIterator in the READY state always returns a non-null pointer
+ // from Data().
+ CheckedAdvanceIteratorStateOnly(iterator, 0, 1, chunkLength,
+ AdvanceMode::eAdvanceByLengthExactly);
+
+ // Advance through the first chunk. As in the |SubchunkAdvance| test, the
+ // chunk count should not increase. We do a zero-length advance after each
+ // normal advance to ensure that zero-length advances do not change the
+ // iterator's position or cause a new chunk to be read.
+ size_t offset = 0;
+ while (offset < chunkLength) {
+ CheckedAdvanceIteratorStateOnly(iterator, 1, 1, chunkLength,
+ AdvanceMode::eAdvanceByLengthExactly);
+ CheckData(iterator.Data(), offset++, iterator.Length());
+ CheckedAdvanceIteratorStateOnly(iterator, 0, 1, chunkLength,
+ AdvanceMode::eAdvanceByLengthExactly);
+ }
+
+ // Read the first byte of the second chunk. This is the point at which we
+ // can't advance within the same chunk, so the chunk count should increase. As
+ // before, we do a zero-length advance afterward.
+ CheckedAdvanceIteratorStateOnly(iterator, 1, 2, totalLength,
+ AdvanceMode::eAdvanceByLengthExactly);
+ CheckData(iterator.Data(), offset++, iterator.Length());
+ CheckedAdvanceIteratorStateOnly(iterator, 0, 2, totalLength,
+ AdvanceMode::eAdvanceByLengthExactly);
+
+ // Read the rest of the second chunk. The chunk count should not increase. As
+ // before, we do a zero-length advance after each normal advance.
+ while (offset < totalLength) {
+ CheckedAdvanceIteratorStateOnly(iterator, 1, 2, totalLength,
+ AdvanceMode::eAdvanceByLengthExactly);
+ CheckData(iterator.Data(), offset++, iterator.Length());
+ CheckedAdvanceIteratorStateOnly(iterator, 0, 2, totalLength,
+ AdvanceMode::eAdvanceByLengthExactly);
+ }
+
+ // Make sure we reached the end.
+ CheckIteratorIsComplete(iterator, 2, totalLength);
+}
+
+TEST_F(ImageSourceBuffer, SubchunkZeroByteAdvanceWithNoData) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Check that advancing by zero bytes still makes us enter the WAITING state.
+ // This is because if we entered the READY state before reading any data at
+ // all, we'd break the invariant that SourceBufferIterator::Data() always
+ // returns a non-null pointer in the READY state.
+ auto state = iterator.AdvanceOrScheduleResume(0, mCountResumes);
+ EXPECT_EQ(SourceBufferIterator::WAITING, state);
+
+ // Call Complete(). This should trigger a resume.
+ CheckedCompleteBuffer();
+ EXPECT_EQ(1u, mCountResumes->Count());
+}
+
+TEST_F(ImageSourceBuffer, NullIResumable) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Check that we can't advance.
+ CheckIteratorMustWait(iterator, nullptr);
+
+ // Append to the buffer, which would cause a resume if we had passed a
+ // non-null IResumable.
+ CheckedAppendToBuffer(mData, sizeof(mData));
+ CheckedCompleteBuffer(iterator, sizeof(mData));
+}
+
+TEST_F(ImageSourceBuffer, AppendTriggersResume) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Check that we can't advance.
+ CheckIteratorMustWait(iterator, mCountResumes);
+
+ // Call Append(). This should trigger a resume.
+ mSourceBuffer->Append(mData, sizeof(mData));
+ EXPECT_EQ(1u, mCountResumes->Count());
+}
+
+TEST_F(ImageSourceBuffer, OnlyOneResumeTriggeredPerAppend) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Check that we can't advance.
+ CheckIteratorMustWait(iterator, mCountResumes);
+
+ // Allocate some data we'll use below.
+ constexpr size_t firstWriteLength = SourceBuffer::MIN_CHUNK_CAPACITY / 2;
+ constexpr size_t secondWriteLength = 3 * SourceBuffer::MIN_CHUNK_CAPACITY;
+ constexpr size_t totalLength = firstWriteLength + secondWriteLength;
+ char data[totalLength];
+ GenerateData(data, sizeof(data));
+
+ // Write half of SourceBuffer::MIN_CHUNK_CAPACITY bytes of test data to the
+ // buffer in a single Append() call. This should fill half of the first chunk.
+ // This should trigger a resume.
+ CheckedAppendToBuffer(data, firstWriteLength);
+ EXPECT_EQ(1u, mCountResumes->Count());
+
+ // Advance past the new data and wait again.
+ CheckedAdvanceIterator(iterator, firstWriteLength);
+ CheckIteratorMustWait(iterator, mCountResumes);
+
+ // Write three times SourceBuffer::MIN_CHUNK_CAPACITY bytes of test data to
+ // the buffer in a single Append() call. We expect this to result in the first
+ // of the first chunk being filled and a new chunk being allocated for the
+ // remainder. Even though two chunks are getting written to here, only *one*
+ // resume should get triggered, for a total of two in this test.
+ CheckedAppendToBuffer(data + firstWriteLength, secondWriteLength);
+ EXPECT_EQ(2u, mCountResumes->Count());
+}
+
+TEST_F(ImageSourceBuffer, CompleteTriggersResume) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Check that we can't advance.
+ CheckIteratorMustWait(iterator, mCountResumes);
+
+ // Call Complete(). This should trigger a resume.
+ CheckedCompleteBuffer();
+ EXPECT_EQ(1u, mCountResumes->Count());
+}
+
+TEST_F(ImageSourceBuffer, ExpectLengthDoesNotTriggerResume) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+
+ // Check that we can't advance.
+ CheckIteratorMustWait(iterator, mExpectNoResume);
+
+ // Call ExpectLength(). If this triggers a resume, |mExpectNoResume| will
+ // ensure that the test fails.
+ mSourceBuffer->ExpectLength(1000);
+}
+
+TEST_F(ImageSourceBuffer, CompleteSuccessWithSameReadLength) {
+ SourceBufferIterator iterator = mSourceBuffer->Iterator(1);
+
+ // Write a single byte to the buffer and complete the buffer. (We have to
+ // write at least one byte because completing a zero length buffer always
+ // fails; see the ZeroLengthBufferAlwaysFails test.)
+ CheckedAppendToBuffer(mData, 1);
+ CheckedCompleteBuffer(iterator, 1);
+
+ // We should be able to advance once (to read the single byte) and then should
+ // reach the COMPLETE state with a successful status.
+ CheckedAdvanceIterator(iterator, 1);
+ CheckIteratorIsComplete(iterator, 1);
+}
+
+TEST_F(ImageSourceBuffer, CompleteSuccessWithSmallerReadLength) {
+ // Create an iterator limited to one byte.
+ SourceBufferIterator iterator = mSourceBuffer->Iterator(1);
+
+ // Write two bytes to the buffer and complete the buffer. (We have to
+ // write at least one byte because completing a zero length buffer always
+ // fails; see the ZeroLengthBufferAlwaysFails test.)
+ CheckedAppendToBuffer(mData, 2);
+ CheckedCompleteBuffer(iterator, 2);
+
+ // We should be able to advance once (to read the single byte) and then should
+ // reach the COMPLETE state with a successful status, because our iterator is
+ // limited to a single byte, rather than the full length.
+ CheckedAdvanceIterator(iterator, 1);
+ CheckIteratorIsComplete(iterator, 1);
+}
+
+TEST_F(ImageSourceBuffer, CompleteSuccessWithGreaterReadLength) {
+ // Create an iterator limited to one byte.
+ SourceBufferIterator iterator = mSourceBuffer->Iterator(2);
+
+ // Write a single byte to the buffer and complete the buffer. (We have to
+ // write at least one byte because completing a zero length buffer always
+ // fails; see the ZeroLengthBufferAlwaysFails test.)
+ CheckedAppendToBuffer(mData, 1);
+ CheckedCompleteBuffer(iterator, 1);
+
+ // We should be able to advance once (to read the single byte) and then should
+ // reach the COMPLETE state with a successful status. Our iterator lets us
+ // read more but the underlying buffer has been completed.
+ CheckedAdvanceIterator(iterator, 1);
+ CheckIteratorIsComplete(iterator, 1);
+}
diff --git a/image/test/gtest/TestStreamingLexer.cpp b/image/test/gtest/TestStreamingLexer.cpp
new file mode 100644
index 0000000000..c83569a7b9
--- /dev/null
+++ b/image/test/gtest/TestStreamingLexer.cpp
@@ -0,0 +1,935 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "Common.h"
+#include "mozilla/Vector.h"
+#include "StreamingLexer.h"
+
+using namespace mozilla;
+using namespace mozilla::image;
+
+enum class TestState {
+ ONE,
+ TWO,
+ THREE,
+ UNBUFFERED,
+ TRUNCATED_SUCCESS,
+ TRUNCATED_FAILURE
+};
+
+void CheckLexedData(const char* aData, size_t aLength, size_t aOffset,
+ size_t aExpectedLength) {
+ EXPECT_TRUE(aLength == aExpectedLength);
+
+ for (size_t i = 0; i < aLength; ++i) {
+ EXPECT_EQ(aData[i], char(aOffset + i + 1));
+ }
+}
+
+LexerTransition<TestState> DoLex(TestState aState, const char* aData,
+ size_t aLength) {
+ switch (aState) {
+ case TestState::ONE:
+ CheckLexedData(aData, aLength, 0, 3);
+ return Transition::To(TestState::TWO, 3);
+ case TestState::TWO:
+ CheckLexedData(aData, aLength, 3, 3);
+ return Transition::To(TestState::THREE, 3);
+ case TestState::THREE:
+ CheckLexedData(aData, aLength, 6, 3);
+ return Transition::TerminateSuccess();
+ case TestState::TRUNCATED_SUCCESS:
+ return Transition::TerminateSuccess();
+ case TestState::TRUNCATED_FAILURE:
+ return Transition::TerminateFailure();
+ default:
+ MOZ_CRASH("Unexpected or unhandled TestState");
+ }
+}
+
+LexerTransition<TestState> DoLexWithUnbuffered(
+ TestState aState, const char* aData, size_t aLength,
+ Vector<char>& aUnbufferedVector) {
+ switch (aState) {
+ case TestState::ONE:
+ CheckLexedData(aData, aLength, 0, 3);
+ return Transition::ToUnbuffered(TestState::TWO, TestState::UNBUFFERED, 3);
+ case TestState::TWO:
+ CheckLexedData(aUnbufferedVector.begin(), aUnbufferedVector.length(), 3,
+ 3);
+ return Transition::To(TestState::THREE, 3);
+ case TestState::THREE:
+ CheckLexedData(aData, aLength, 6, 3);
+ return Transition::TerminateSuccess();
+ case TestState::UNBUFFERED:
+ EXPECT_TRUE(aLength <= 3);
+ EXPECT_TRUE(aUnbufferedVector.append(aData, aLength));
+ return Transition::ContinueUnbuffered(TestState::UNBUFFERED);
+ default:
+ MOZ_CRASH("Unexpected or unhandled TestState");
+ }
+}
+
+LexerTransition<TestState> DoLexWithUnbufferedTerminate(TestState aState,
+ const char* aData,
+ size_t aLength) {
+ switch (aState) {
+ case TestState::ONE:
+ CheckLexedData(aData, aLength, 0, 3);
+ return Transition::ToUnbuffered(TestState::TWO, TestState::UNBUFFERED, 3);
+ case TestState::UNBUFFERED:
+ return Transition::TerminateSuccess();
+ default:
+ MOZ_CRASH("Unexpected or unhandled TestState");
+ }
+}
+
+LexerTransition<TestState> DoLexWithYield(TestState aState, const char* aData,
+ size_t aLength) {
+ switch (aState) {
+ case TestState::ONE:
+ CheckLexedData(aData, aLength, 0, 3);
+ return Transition::ToAfterYield(TestState::TWO);
+ case TestState::TWO:
+ CheckLexedData(aData, aLength, 0, 3);
+ return Transition::To(TestState::THREE, 6);
+ case TestState::THREE:
+ CheckLexedData(aData, aLength, 3, 6);
+ return Transition::TerminateSuccess();
+ default:
+ MOZ_CRASH("Unexpected or unhandled TestState");
+ }
+}
+
+LexerTransition<TestState> DoLexWithTerminateAfterYield(TestState aState,
+ const char* aData,
+ size_t aLength) {
+ switch (aState) {
+ case TestState::ONE:
+ CheckLexedData(aData, aLength, 0, 3);
+ return Transition::ToAfterYield(TestState::TWO);
+ case TestState::TWO:
+ return Transition::TerminateSuccess();
+ default:
+ MOZ_CRASH("Unexpected or unhandled TestState");
+ }
+}
+
+LexerTransition<TestState> DoLexWithZeroLengthStates(TestState aState,
+ const char* aData,
+ size_t aLength) {
+ switch (aState) {
+ case TestState::ONE:
+ EXPECT_TRUE(aLength == 0);
+ return Transition::To(TestState::TWO, 0);
+ case TestState::TWO:
+ EXPECT_TRUE(aLength == 0);
+ return Transition::To(TestState::THREE, 9);
+ case TestState::THREE:
+ CheckLexedData(aData, aLength, 0, 9);
+ return Transition::TerminateSuccess();
+ default:
+ MOZ_CRASH("Unexpected or unhandled TestState");
+ }
+}
+
+LexerTransition<TestState> DoLexWithZeroLengthStatesAtEnd(TestState aState,
+ const char* aData,
+ size_t aLength) {
+ switch (aState) {
+ case TestState::ONE:
+ CheckLexedData(aData, aLength, 0, 9);
+ return Transition::To(TestState::TWO, 0);
+ case TestState::TWO:
+ EXPECT_TRUE(aLength == 0);
+ return Transition::To(TestState::THREE, 0);
+ case TestState::THREE:
+ EXPECT_TRUE(aLength == 0);
+ return Transition::TerminateSuccess();
+ default:
+ MOZ_CRASH("Unexpected or unhandled TestState");
+ }
+}
+
+LexerTransition<TestState> DoLexWithZeroLengthYield(TestState aState,
+ const char* aData,
+ size_t aLength) {
+ switch (aState) {
+ case TestState::ONE:
+ EXPECT_EQ(0u, aLength);
+ return Transition::ToAfterYield(TestState::TWO);
+ case TestState::TWO:
+ EXPECT_EQ(0u, aLength);
+ return Transition::To(TestState::THREE, 9);
+ case TestState::THREE:
+ CheckLexedData(aData, aLength, 0, 9);
+ return Transition::TerminateSuccess();
+ default:
+ MOZ_CRASH("Unexpected or unhandled TestState");
+ }
+}
+
+LexerTransition<TestState> DoLexWithZeroLengthStatesUnbuffered(
+ TestState aState, const char* aData, size_t aLength) {
+ switch (aState) {
+ case TestState::ONE:
+ EXPECT_TRUE(aLength == 0);
+ return Transition::ToUnbuffered(TestState::TWO, TestState::UNBUFFERED, 0);
+ case TestState::TWO:
+ EXPECT_TRUE(aLength == 0);
+ return Transition::To(TestState::THREE, 9);
+ case TestState::THREE:
+ CheckLexedData(aData, aLength, 0, 9);
+ return Transition::TerminateSuccess();
+ case TestState::UNBUFFERED:
+ ADD_FAILURE() << "Should not enter zero-length unbuffered state";
+ return Transition::TerminateFailure();
+ default:
+ MOZ_CRASH("Unexpected or unhandled TestState");
+ }
+}
+
+LexerTransition<TestState> DoLexWithZeroLengthStatesAfterUnbuffered(
+ TestState aState, const char* aData, size_t aLength) {
+ switch (aState) {
+ case TestState::ONE:
+ EXPECT_TRUE(aLength == 0);
+ return Transition::ToUnbuffered(TestState::TWO, TestState::UNBUFFERED, 9);
+ case TestState::TWO:
+ EXPECT_TRUE(aLength == 0);
+ return Transition::To(TestState::THREE, 0);
+ case TestState::THREE:
+ EXPECT_TRUE(aLength == 0);
+ return Transition::TerminateSuccess();
+ case TestState::UNBUFFERED:
+ CheckLexedData(aData, aLength, 0, 9);
+ return Transition::ContinueUnbuffered(TestState::UNBUFFERED);
+ default:
+ MOZ_CRASH("Unexpected or unhandled TestState");
+ }
+}
+
+class ImageStreamingLexer : public ::testing::Test {
+ public:
+ // Note that mLexer is configured to enter TerminalState::FAILURE immediately
+ // if the input data is truncated. We don't expect that to happen in most
+ // tests, so we want to detect that issue. If a test needs a different
+ // behavior, we create a special StreamingLexer just for that test.
+ ImageStreamingLexer()
+ : mLexer(Transition::To(TestState::ONE, 3),
+ Transition::TerminateFailure()),
+ mSourceBuffer(new SourceBuffer),
+ mIterator(mSourceBuffer->Iterator()),
+ mExpectNoResume(new ExpectNoResume),
+ mCountResumes(new CountResumes) {}
+
+ protected:
+ void CheckTruncatedState(StreamingLexer<TestState>& aLexer,
+ TerminalState aExpectedTerminalState,
+ nsresult aCompletionStatus = NS_OK) {
+ for (unsigned i = 0; i < 9; ++i) {
+ if (i < 2) {
+ mSourceBuffer->Append(mData + i, 1);
+ } else if (i == 2) {
+ mSourceBuffer->Complete(aCompletionStatus);
+ }
+
+ LexerResult result = aLexer.Lex(mIterator, mCountResumes, DoLex);
+
+ if (i >= 2) {
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(aExpectedTerminalState, result.as<TerminalState>());
+ } else {
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+ }
+ }
+
+ EXPECT_EQ(2u, mCountResumes->Count());
+ }
+
+ AutoInitializeImageLib mInit;
+ const char mData[9]{1, 2, 3, 4, 5, 6, 7, 8, 9};
+ StreamingLexer<TestState> mLexer;
+ RefPtr<SourceBuffer> mSourceBuffer;
+ SourceBufferIterator mIterator;
+ RefPtr<ExpectNoResume> mExpectNoResume;
+ RefPtr<CountResumes> mCountResumes;
+};
+
+TEST_F(ImageStreamingLexer, ZeroLengthData) {
+ // Test a zero-length input.
+ mSourceBuffer->Complete(NS_OK);
+
+ LexerResult result = mLexer.Lex(mIterator, mExpectNoResume, DoLex);
+
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::FAILURE, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, ZeroLengthDataUnbuffered) {
+ // Test a zero-length input.
+ mSourceBuffer->Complete(NS_OK);
+
+ // Create a special StreamingLexer for this test because we want the first
+ // state to be unbuffered.
+ StreamingLexer<TestState> lexer(
+ Transition::ToUnbuffered(TestState::ONE, TestState::UNBUFFERED,
+ sizeof(mData)),
+ Transition::TerminateFailure());
+
+ LexerResult result = lexer.Lex(mIterator, mExpectNoResume, DoLex);
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::FAILURE, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, StartWithTerminal) {
+ // Create a special StreamingLexer for this test because we want the first
+ // state to be a terminal state. This doesn't really make sense, but we should
+ // handle it.
+ StreamingLexer<TestState> lexer(Transition::TerminateSuccess(),
+ Transition::TerminateFailure());
+ LexerResult result = lexer.Lex(mIterator, mExpectNoResume, DoLex);
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+
+ mSourceBuffer->Complete(NS_OK);
+}
+
+TEST_F(ImageStreamingLexer, SingleChunk) {
+ // Test delivering all the data at once.
+ mSourceBuffer->Append(mData, sizeof(mData));
+ mSourceBuffer->Complete(NS_OK);
+
+ LexerResult result = mLexer.Lex(mIterator, mExpectNoResume, DoLex);
+
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, SingleChunkWithUnbuffered) {
+ Vector<char> unbufferedVector;
+
+ // Test delivering all the data at once.
+ mSourceBuffer->Append(mData, sizeof(mData));
+ mSourceBuffer->Complete(NS_OK);
+
+ LexerResult result = mLexer.Lex(
+ mIterator, mExpectNoResume,
+ [&](TestState aState, const char* aData, size_t aLength) {
+ return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector);
+ });
+
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, SingleChunkWithYield) {
+ // Test delivering all the data at once.
+ mSourceBuffer->Append(mData, sizeof(mData));
+ mSourceBuffer->Complete(NS_OK);
+
+ LexerResult result = mLexer.Lex(mIterator, mExpectNoResume, DoLexWithYield);
+ ASSERT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::OUTPUT_AVAILABLE, result.as<Yield>());
+
+ result = mLexer.Lex(mIterator, mExpectNoResume, DoLexWithYield);
+ ASSERT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, ChunkPerState) {
+ // Test delivering in perfectly-sized chunks, one per state.
+ for (unsigned i = 0; i < 3; ++i) {
+ mSourceBuffer->Append(mData + 3 * i, 3);
+ LexerResult result = mLexer.Lex(mIterator, mCountResumes, DoLex);
+
+ if (i == 2) {
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+ } else {
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+ }
+ }
+
+ EXPECT_EQ(2u, mCountResumes->Count());
+ mSourceBuffer->Complete(NS_OK);
+}
+
+TEST_F(ImageStreamingLexer, ChunkPerStateWithUnbuffered) {
+ Vector<char> unbufferedVector;
+
+ // Test delivering in perfectly-sized chunks, one per state.
+ for (unsigned i = 0; i < 3; ++i) {
+ mSourceBuffer->Append(mData + 3 * i, 3);
+ LexerResult result = mLexer.Lex(
+ mIterator, mCountResumes,
+ [&](TestState aState, const char* aData, size_t aLength) {
+ return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector);
+ });
+
+ if (i == 2) {
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+ } else {
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+ }
+ }
+
+ EXPECT_EQ(2u, mCountResumes->Count());
+ mSourceBuffer->Complete(NS_OK);
+}
+
+TEST_F(ImageStreamingLexer, ChunkPerStateWithYield) {
+ // Test delivering in perfectly-sized chunks, one per state.
+ mSourceBuffer->Append(mData, 3);
+ LexerResult result = mLexer.Lex(mIterator, mCountResumes, DoLexWithYield);
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::OUTPUT_AVAILABLE, result.as<Yield>());
+
+ result = mLexer.Lex(mIterator, mCountResumes, DoLexWithYield);
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+
+ mSourceBuffer->Append(mData + 3, 6);
+ result = mLexer.Lex(mIterator, mCountResumes, DoLexWithYield);
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+
+ EXPECT_EQ(1u, mCountResumes->Count());
+ mSourceBuffer->Complete(NS_OK);
+}
+
+TEST_F(ImageStreamingLexer, ChunkPerStateWithUnbufferedYield) {
+ size_t unbufferedCallCount = 0;
+ Vector<char> unbufferedVector;
+ auto lexerFunc = [&](TestState aState, const char* aData,
+ size_t aLength) -> LexerTransition<TestState> {
+ switch (aState) {
+ case TestState::ONE:
+ CheckLexedData(aData, aLength, 0, 3);
+ return Transition::ToUnbuffered(TestState::TWO, TestState::UNBUFFERED,
+ 3);
+ case TestState::TWO:
+ CheckLexedData(unbufferedVector.begin(), unbufferedVector.length(), 3,
+ 3);
+ return Transition::To(TestState::THREE, 3);
+ case TestState::THREE:
+ CheckLexedData(aData, aLength, 6, 3);
+ return Transition::TerminateSuccess();
+ case TestState::UNBUFFERED:
+ switch (unbufferedCallCount) {
+ case 0:
+ CheckLexedData(aData, aLength, 3, 3);
+ EXPECT_TRUE(unbufferedVector.append(aData, 2));
+ unbufferedCallCount++;
+
+ // Continue after yield, telling StreamingLexer we consumed 2 bytes.
+ return Transition::ContinueUnbufferedAfterYield(
+ TestState::UNBUFFERED, 2);
+
+ case 1:
+ CheckLexedData(aData, aLength, 5, 1);
+ EXPECT_TRUE(unbufferedVector.append(aData, 1));
+ unbufferedCallCount++;
+
+ // Continue after yield, telling StreamingLexer we consumed 1 byte.
+ // We should end up in the TWO state.
+ return Transition::ContinueUnbuffered(TestState::UNBUFFERED);
+ }
+ ADD_FAILURE() << "Too many invocations of TestState::UNBUFFERED";
+ return Transition::TerminateFailure();
+ default:
+ MOZ_CRASH("Unexpected or unhandled TestState");
+ }
+ };
+
+ // Test delivering in perfectly-sized chunks, one per state.
+ for (unsigned i = 0; i < 3; ++i) {
+ mSourceBuffer->Append(mData + 3 * i, 3);
+ LexerResult result = mLexer.Lex(mIterator, mCountResumes, lexerFunc);
+
+ switch (i) {
+ case 0:
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+ EXPECT_EQ(0u, unbufferedCallCount);
+ break;
+
+ case 1:
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::OUTPUT_AVAILABLE, result.as<Yield>());
+ EXPECT_EQ(1u, unbufferedCallCount);
+
+ result = mLexer.Lex(mIterator, mCountResumes, lexerFunc);
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+ EXPECT_EQ(2u, unbufferedCallCount);
+ break;
+
+ case 2:
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+ break;
+ }
+ }
+
+ EXPECT_EQ(2u, mCountResumes->Count());
+ mSourceBuffer->Complete(NS_OK);
+
+ LexerResult result = mLexer.Lex(mIterator, mCountResumes, lexerFunc);
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, OneByteChunks) {
+ // Test delivering in one byte chunks.
+ for (unsigned i = 0; i < 9; ++i) {
+ mSourceBuffer->Append(mData + i, 1);
+ LexerResult result = mLexer.Lex(mIterator, mCountResumes, DoLex);
+
+ if (i == 8) {
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+ } else {
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+ }
+ }
+
+ EXPECT_EQ(8u, mCountResumes->Count());
+ mSourceBuffer->Complete(NS_OK);
+}
+
+TEST_F(ImageStreamingLexer, OneByteChunksWithUnbuffered) {
+ Vector<char> unbufferedVector;
+
+ // Test delivering in one byte chunks.
+ for (unsigned i = 0; i < 9; ++i) {
+ mSourceBuffer->Append(mData + i, 1);
+ LexerResult result = mLexer.Lex(
+ mIterator, mCountResumes,
+ [&](TestState aState, const char* aData, size_t aLength) {
+ return DoLexWithUnbuffered(aState, aData, aLength, unbufferedVector);
+ });
+
+ if (i == 8) {
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+ } else {
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+ }
+ }
+
+ EXPECT_EQ(8u, mCountResumes->Count());
+ mSourceBuffer->Complete(NS_OK);
+}
+
+TEST_F(ImageStreamingLexer, OneByteChunksWithYield) {
+ // Test delivering in one byte chunks.
+ for (unsigned i = 0; i < 9; ++i) {
+ mSourceBuffer->Append(mData + i, 1);
+ LexerResult result = mLexer.Lex(mIterator, mCountResumes, DoLexWithYield);
+
+ switch (i) {
+ case 2:
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::OUTPUT_AVAILABLE, result.as<Yield>());
+
+ result = mLexer.Lex(mIterator, mCountResumes, DoLexWithYield);
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+ break;
+
+ case 8:
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+ break;
+
+ default:
+ EXPECT_TRUE(i < 9);
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+ }
+ }
+
+ EXPECT_EQ(8u, mCountResumes->Count());
+ mSourceBuffer->Complete(NS_OK);
+}
+
+TEST_F(ImageStreamingLexer, ZeroLengthState) {
+ mSourceBuffer->Append(mData, sizeof(mData));
+ mSourceBuffer->Complete(NS_OK);
+
+ // Create a special StreamingLexer for this test because we want the first
+ // state to be zero length.
+ StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 0),
+ Transition::TerminateFailure());
+
+ LexerResult result =
+ lexer.Lex(mIterator, mExpectNoResume, DoLexWithZeroLengthStates);
+
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, ZeroLengthStatesAtEnd) {
+ mSourceBuffer->Append(mData, sizeof(mData));
+ mSourceBuffer->Complete(NS_OK);
+
+ // Create a special StreamingLexer for this test because we want the first
+ // state to consume the full input.
+ StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 9),
+ Transition::TerminateFailure());
+
+ LexerResult result =
+ lexer.Lex(mIterator, mExpectNoResume, DoLexWithZeroLengthStatesAtEnd);
+
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, ZeroLengthStateWithYield) {
+ // Create a special StreamingLexer for this test because we want the first
+ // state to be zero length.
+ StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 0),
+ Transition::TerminateFailure());
+
+ mSourceBuffer->Append(mData, 3);
+ LexerResult result =
+ lexer.Lex(mIterator, mExpectNoResume, DoLexWithZeroLengthYield);
+ ASSERT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::OUTPUT_AVAILABLE, result.as<Yield>());
+
+ result = lexer.Lex(mIterator, mCountResumes, DoLexWithZeroLengthYield);
+ ASSERT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+
+ mSourceBuffer->Append(mData + 3, sizeof(mData) - 3);
+ mSourceBuffer->Complete(NS_OK);
+ result = lexer.Lex(mIterator, mExpectNoResume, DoLexWithZeroLengthYield);
+ ASSERT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+ EXPECT_EQ(1u, mCountResumes->Count());
+}
+
+TEST_F(ImageStreamingLexer, ZeroLengthStateWithUnbuffered) {
+ mSourceBuffer->Append(mData, sizeof(mData));
+ mSourceBuffer->Complete(NS_OK);
+
+ // Create a special StreamingLexer for this test because we want the first
+ // state to be both zero length and unbuffered.
+ StreamingLexer<TestState> lexer(
+ Transition::ToUnbuffered(TestState::ONE, TestState::UNBUFFERED, 0),
+ Transition::TerminateFailure());
+
+ LexerResult result = lexer.Lex(mIterator, mExpectNoResume,
+ DoLexWithZeroLengthStatesUnbuffered);
+
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, ZeroLengthStateAfterUnbuffered) {
+ mSourceBuffer->Append(mData, sizeof(mData));
+ mSourceBuffer->Complete(NS_OK);
+
+ // Create a special StreamingLexer for this test because we want the first
+ // state to be zero length.
+ StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 0),
+ Transition::TerminateFailure());
+
+ LexerResult result = lexer.Lex(mIterator, mExpectNoResume,
+ DoLexWithZeroLengthStatesAfterUnbuffered);
+
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, ZeroLengthStateWithUnbufferedYield) {
+ size_t unbufferedCallCount = 0;
+ auto lexerFunc = [&](TestState aState, const char* aData,
+ size_t aLength) -> LexerTransition<TestState> {
+ switch (aState) {
+ case TestState::ONE:
+ EXPECT_EQ(0u, aLength);
+ return Transition::TerminateSuccess();
+
+ case TestState::UNBUFFERED:
+ switch (unbufferedCallCount) {
+ case 0:
+ CheckLexedData(aData, aLength, 0, 3);
+ unbufferedCallCount++;
+
+ // Continue after yield, telling StreamingLexer we consumed 0 bytes.
+ return Transition::ContinueUnbufferedAfterYield(
+ TestState::UNBUFFERED, 0);
+
+ case 1:
+ CheckLexedData(aData, aLength, 0, 3);
+ unbufferedCallCount++;
+
+ // Continue after yield, telling StreamingLexer we consumed 2 bytes.
+ return Transition::ContinueUnbufferedAfterYield(
+ TestState::UNBUFFERED, 2);
+
+ case 2:
+ EXPECT_EQ(1u, aLength);
+ CheckLexedData(aData, aLength, 2, 1);
+ unbufferedCallCount++;
+
+ // Continue after yield, telling StreamingLexer we consumed 1 bytes.
+ return Transition::ContinueUnbufferedAfterYield(
+ TestState::UNBUFFERED, 1);
+
+ case 3:
+ CheckLexedData(aData, aLength, 3, 6);
+ unbufferedCallCount++;
+
+ // Continue after yield, telling StreamingLexer we consumed 6 bytes.
+ // We should transition to TestState::ONE when we return from the
+ // yield.
+ return Transition::ContinueUnbufferedAfterYield(
+ TestState::UNBUFFERED, 6);
+ }
+
+ ADD_FAILURE() << "Too many invocations of TestState::UNBUFFERED";
+ return Transition::TerminateFailure();
+
+ default:
+ MOZ_CRASH("Unexpected or unhandled TestState");
+ }
+ };
+
+ // Create a special StreamingLexer for this test because we want the first
+ // state to be unbuffered.
+ StreamingLexer<TestState> lexer(
+ Transition::ToUnbuffered(TestState::ONE, TestState::UNBUFFERED,
+ sizeof(mData)),
+ Transition::TerminateFailure());
+
+ mSourceBuffer->Append(mData, 3);
+ LexerResult result = lexer.Lex(mIterator, mExpectNoResume, lexerFunc);
+ ASSERT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::OUTPUT_AVAILABLE, result.as<Yield>());
+ EXPECT_EQ(1u, unbufferedCallCount);
+
+ result = lexer.Lex(mIterator, mExpectNoResume, lexerFunc);
+ ASSERT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::OUTPUT_AVAILABLE, result.as<Yield>());
+ EXPECT_EQ(2u, unbufferedCallCount);
+
+ result = lexer.Lex(mIterator, mExpectNoResume, lexerFunc);
+ ASSERT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::OUTPUT_AVAILABLE, result.as<Yield>());
+ EXPECT_EQ(3u, unbufferedCallCount);
+
+ result = lexer.Lex(mIterator, mCountResumes, lexerFunc);
+ ASSERT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+ EXPECT_EQ(3u, unbufferedCallCount);
+
+ mSourceBuffer->Append(mData + 3, 6);
+ mSourceBuffer->Complete(NS_OK);
+ EXPECT_EQ(1u, mCountResumes->Count());
+ result = lexer.Lex(mIterator, mExpectNoResume, lexerFunc);
+ ASSERT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::OUTPUT_AVAILABLE, result.as<Yield>());
+ EXPECT_EQ(4u, unbufferedCallCount);
+
+ result = lexer.Lex(mIterator, mExpectNoResume, lexerFunc);
+ ASSERT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, TerminateSuccess) {
+ mSourceBuffer->Append(mData, sizeof(mData));
+ mSourceBuffer->Complete(NS_OK);
+
+ // Test that Terminate is "sticky".
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+ LexerResult result =
+ mLexer.Lex(iterator, mExpectNoResume,
+ [&](TestState aState, const char* aData, size_t aLength) {
+ EXPECT_TRUE(aState == TestState::ONE);
+ return Transition::TerminateSuccess();
+ });
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+
+ SourceBufferIterator iterator2 = mSourceBuffer->Iterator();
+ result = mLexer.Lex(iterator2, mExpectNoResume,
+ [&](TestState aState, const char* aData, size_t aLength) {
+ EXPECT_TRUE(false); // Shouldn't get here.
+ return Transition::TerminateFailure();
+ });
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, TerminateFailure) {
+ mSourceBuffer->Append(mData, sizeof(mData));
+ mSourceBuffer->Complete(NS_OK);
+
+ // Test that Terminate is "sticky".
+ SourceBufferIterator iterator = mSourceBuffer->Iterator();
+ LexerResult result =
+ mLexer.Lex(iterator, mExpectNoResume,
+ [&](TestState aState, const char* aData, size_t aLength) {
+ EXPECT_TRUE(aState == TestState::ONE);
+ return Transition::TerminateFailure();
+ });
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::FAILURE, result.as<TerminalState>());
+
+ SourceBufferIterator iterator2 = mSourceBuffer->Iterator();
+ result = mLexer.Lex(iterator2, mExpectNoResume,
+ [&](TestState aState, const char* aData, size_t aLength) {
+ EXPECT_TRUE(false); // Shouldn't get here.
+ return Transition::TerminateFailure();
+ });
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::FAILURE, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, TerminateUnbuffered) {
+ // Test that Terminate works during an unbuffered read.
+ for (unsigned i = 0; i < 9; ++i) {
+ mSourceBuffer->Append(mData + i, 1);
+ LexerResult result =
+ mLexer.Lex(mIterator, mCountResumes, DoLexWithUnbufferedTerminate);
+
+ if (i > 2) {
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+ } else {
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+ }
+ }
+
+ // We expect 3 resumes because TestState::ONE consumes 3 bytes and then
+ // transitions to TestState::UNBUFFERED, which calls TerminateSuccess() as
+ // soon as it receives a single byte. That's four bytes total, which are
+ // delivered one at a time, requiring 3 resumes.
+ EXPECT_EQ(3u, mCountResumes->Count());
+
+ mSourceBuffer->Complete(NS_OK);
+}
+
+TEST_F(ImageStreamingLexer, TerminateAfterYield) {
+ // Test that Terminate works after yielding.
+ for (unsigned i = 0; i < 9; ++i) {
+ mSourceBuffer->Append(mData + i, 1);
+ LexerResult result =
+ mLexer.Lex(mIterator, mCountResumes, DoLexWithTerminateAfterYield);
+
+ if (i > 2) {
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+ } else if (i == 2) {
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::OUTPUT_AVAILABLE, result.as<Yield>());
+ } else {
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+ }
+ }
+
+ // We expect 2 resumes because TestState::ONE consumes 3 bytes and then
+ // yields. When the lexer resumes at TestState::TWO, which receives the same 3
+ // bytes, TerminateSuccess() gets called immediately. That's three bytes
+ // total, which are delivered one at a time, requiring 2 resumes.
+ EXPECT_EQ(2u, mCountResumes->Count());
+
+ mSourceBuffer->Complete(NS_OK);
+}
+
+TEST_F(ImageStreamingLexer, SourceBufferImmediateComplete) {
+ // Test calling SourceBuffer::Complete() without appending any data. This
+ // causes the SourceBuffer to automatically have a failing completion status,
+ // no matter what you pass, so we expect TerminalState::FAILURE below.
+ mSourceBuffer->Complete(NS_OK);
+
+ LexerResult result = mLexer.Lex(mIterator, mExpectNoResume, DoLex);
+
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::FAILURE, result.as<TerminalState>());
+}
+
+TEST_F(ImageStreamingLexer, SourceBufferTruncatedTerminalStateSuccess) {
+ // Test that using a terminal state (in this case TerminalState::SUCCESS) as a
+ // truncated state works.
+ StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3),
+ Transition::TerminateSuccess());
+
+ CheckTruncatedState(lexer, TerminalState::SUCCESS);
+}
+
+TEST_F(ImageStreamingLexer, SourceBufferTruncatedTerminalStateFailure) {
+ // Test that using a terminal state (in this case TerminalState::FAILURE) as a
+ // truncated state works.
+ StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3),
+ Transition::TerminateFailure());
+
+ CheckTruncatedState(lexer, TerminalState::FAILURE);
+}
+
+TEST_F(ImageStreamingLexer, SourceBufferTruncatedStateReturningSuccess) {
+ // Test that a truncated state that returns TerminalState::SUCCESS works. When
+ // |lexer| discovers that the data is truncated, it invokes the
+ // TRUNCATED_SUCCESS state, which returns TerminalState::SUCCESS.
+ // CheckTruncatedState() verifies that this happens.
+ StreamingLexer<TestState> lexer(
+ Transition::To(TestState::ONE, 3),
+ Transition::To(TestState::TRUNCATED_SUCCESS, 0));
+
+ CheckTruncatedState(lexer, TerminalState::SUCCESS);
+}
+
+TEST_F(ImageStreamingLexer, SourceBufferTruncatedStateReturningFailure) {
+ // Test that a truncated state that returns TerminalState::FAILURE works. When
+ // |lexer| discovers that the data is truncated, it invokes the
+ // TRUNCATED_FAILURE state, which returns TerminalState::FAILURE.
+ // CheckTruncatedState() verifies that this happens.
+ StreamingLexer<TestState> lexer(
+ Transition::To(TestState::ONE, 3),
+ Transition::To(TestState::TRUNCATED_FAILURE, 0));
+
+ CheckTruncatedState(lexer, TerminalState::FAILURE);
+}
+
+TEST_F(ImageStreamingLexer, SourceBufferTruncatedFailingCompleteStatus) {
+ // Test that calling SourceBuffer::Complete() with a failing status results in
+ // an immediate TerminalState::FAILURE result. (Note that |lexer|'s truncated
+ // state is TerminalState::SUCCESS, so if we ignore the failing status, the
+ // test will fail.)
+ StreamingLexer<TestState> lexer(Transition::To(TestState::ONE, 3),
+ Transition::TerminateSuccess());
+
+ CheckTruncatedState(lexer, TerminalState::FAILURE, NS_ERROR_FAILURE);
+}
+
+TEST_F(ImageStreamingLexer, NoSourceBufferResumable) {
+ // Test delivering in one byte chunks with no IResumable.
+ for (unsigned i = 0; i < 9; ++i) {
+ mSourceBuffer->Append(mData + i, 1);
+ LexerResult result = mLexer.Lex(mIterator, nullptr, DoLex);
+
+ if (i == 8) {
+ EXPECT_TRUE(result.is<TerminalState>());
+ EXPECT_EQ(TerminalState::SUCCESS, result.as<TerminalState>());
+ } else {
+ EXPECT_TRUE(result.is<Yield>());
+ EXPECT_EQ(Yield::NEED_MORE_DATA, result.as<Yield>());
+ }
+ }
+
+ mSourceBuffer->Complete(NS_OK);
+}
diff --git a/image/test/gtest/TestSurfaceCache.cpp b/image/test/gtest/TestSurfaceCache.cpp
new file mode 100644
index 0000000000..53193b1a88
--- /dev/null
+++ b/image/test/gtest/TestSurfaceCache.cpp
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "Common.h"
+#include "imgIContainer.h"
+#include "ImageFactory.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/StaticPrefs_image.h"
+#include "nsIInputStream.h"
+#include "nsString.h"
+#include "ProgressTracker.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+class ImageSurfaceCache : public ::testing::Test {
+ protected:
+ AutoInitializeImageLib mInit;
+};
+
+TEST_F(ImageSurfaceCache, Factor2) {
+ ImageTestCase testCase = GreenPNGTestCase();
+
+ // Create an image.
+ RefPtr<Image> image = ImageFactory::CreateAnonymousImage(
+ nsDependentCString(testCase.mMimeType));
+ ASSERT_TRUE(!image->HasError());
+
+ nsCOMPtr<nsIInputStream> inputStream = LoadFile(testCase.mPath);
+ ASSERT_TRUE(inputStream);
+
+ // Figure out how much data we have.
+ uint64_t length;
+ nsresult rv = inputStream->Available(&length);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Ensures we meet the threshold for FLAG_SYNC_DECODE_IF_FAST to do sync
+ // decoding without the implications of FLAG_SYNC_DECODE.
+ ASSERT_LT(length,
+ static_cast<uint64_t>(
+ StaticPrefs::image_mem_decode_bytes_at_a_time_AtStartup()));
+
+ // Write the data into the image.
+ rv = image->OnImageDataAvailable(nullptr, inputStream, 0,
+ static_cast<uint32_t>(length));
+ ASSERT_NS_SUCCEEDED(rv);
+
+ // Let the image know we've sent all the data.
+ rv = image->OnImageDataComplete(nullptr, NS_OK, true);
+ ASSERT_NS_SUCCEEDED(rv);
+
+ RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
+ tracker->SyncNotifyProgress(FLAG_LOAD_COMPLETE);
+
+ const uint32_t whichFrame = imgIContainer::FRAME_CURRENT;
+
+ // FLAG_SYNC_DECODE will make RasterImage::LookupFrame use
+ // SurfaceCache::Lookup to force an exact match lookup (and potential decode).
+ const uint32_t exactFlags = imgIContainer::FLAG_HIGH_QUALITY_SCALING |
+ imgIContainer::FLAG_SYNC_DECODE;
+
+ // If the data stream is small enough, as we assert above,
+ // FLAG_SYNC_DECODE_IF_FAST will allow us to decode sync, but avoid forcing
+ // SurfaceCache::Lookup. Instead it will use SurfaceCache::LookupBestMatch.
+ const uint32_t bestMatchFlags = imgIContainer::FLAG_HIGH_QUALITY_SCALING |
+ imgIContainer::FLAG_SYNC_DECODE_IF_FAST;
+
+ // We need the default threshold to be enabled (otherwise we should disable
+ // this test).
+ int32_t threshold = StaticPrefs::image_cache_factor2_threshold_surfaces();
+ ASSERT_TRUE(threshold >= 0);
+
+ // We need to know what the native sizes are, otherwise factor of 2 mode will
+ // be disabled.
+ size_t nativeSizes = image->GetNativeSizesLength();
+ ASSERT_EQ(nativeSizes, 1u);
+
+ // Threshold is the native size count and the pref threshold added together.
+ // Make sure the image is big enough that we can simply decrement and divide
+ // off the size as we please and not hit unexpected duplicates.
+ int32_t totalThreshold = static_cast<int32_t>(nativeSizes) + threshold;
+ ASSERT_TRUE(testCase.mSize.width > totalThreshold * 4);
+
+ // Request a bunch of slightly different sizes. We won't trip factor of 2 mode
+ // in this loop.
+ IntSize size = testCase.mSize;
+ for (int32_t i = 0; i <= totalThreshold; ++i) {
+ RefPtr<SourceSurface> surf =
+ image->GetFrameAtSize(size, whichFrame, bestMatchFlags);
+ ASSERT_TRUE(surf);
+ EXPECT_EQ(surf->GetSize(), size);
+
+ size.width -= 1;
+ size.height -= 1;
+ }
+
+ // Now let's ask for a new size. Despite this being sync, it will return
+ // the closest factor of 2 size we have and not the requested size.
+ RefPtr<SourceSurface> surf =
+ image->GetFrameAtSize(size, whichFrame, bestMatchFlags);
+ ASSERT_TRUE(surf);
+
+ EXPECT_EQ(surf->GetSize(), testCase.mSize);
+
+ // Now we should be in factor of 2 mode but unless we trigger a decode no
+ // pruning of the old sized surfaces should happen.
+ size = testCase.mSize;
+ for (int32_t i = 0; i < totalThreshold; ++i) {
+ RefPtr<SourceSurface> surf =
+ image->GetFrameAtSize(size, whichFrame, bestMatchFlags);
+ ASSERT_TRUE(surf);
+ EXPECT_EQ(surf->GetSize(), size);
+
+ size.width -= 1;
+ size.height -= 1;
+ }
+
+ // Now force an existing surface to be marked as explicit so that it
+ // won't get freed upon pruning (gets marked in the Lookup).
+ size.width += 1;
+ size.height += 1;
+ surf = image->GetFrameAtSize(size, whichFrame, exactFlags);
+ ASSERT_TRUE(surf);
+ EXPECT_EQ(surf->GetSize(), size);
+
+ // Now force a new decode to happen by getting a new factor of 2 size.
+ size.width = testCase.mSize.width / 2 - 1;
+ size.height = testCase.mSize.height / 2 - 1;
+ surf = image->GetFrameAtSize(size, whichFrame, bestMatchFlags);
+ ASSERT_TRUE(surf);
+ EXPECT_EQ(surf->GetSize().width, testCase.mSize.width / 2);
+ EXPECT_EQ(surf->GetSize().height, testCase.mSize.height / 2);
+
+ // The decode above would have forced a pruning to happen, so now if
+ // we request all of the sizes we used to have decoded, only the explicit
+ // size should have been kept.
+ size = testCase.mSize;
+ for (int32_t i = 0; i < totalThreshold - 1; ++i) {
+ RefPtr<SourceSurface> surf =
+ image->GetFrameAtSize(size, whichFrame, bestMatchFlags);
+ ASSERT_TRUE(surf);
+ EXPECT_EQ(surf->GetSize(), testCase.mSize);
+
+ size.width -= 1;
+ size.height -= 1;
+ }
+
+ // This lookup finds the surface that already existed that we later marked
+ // as explicit. It should still exist after pruning.
+ surf = image->GetFrameAtSize(size, whichFrame, bestMatchFlags);
+ ASSERT_TRUE(surf);
+ EXPECT_EQ(surf->GetSize(), size);
+}
diff --git a/image/test/gtest/TestSurfacePipeIntegration.cpp b/image/test/gtest/TestSurfacePipeIntegration.cpp
new file mode 100644
index 0000000000..0843ce3f77
--- /dev/null
+++ b/image/test/gtest/TestSurfacePipeIntegration.cpp
@@ -0,0 +1,349 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "mozilla/gfx/2D.h"
+#include "Common.h"
+#include "Decoder.h"
+#include "DecoderFactory.h"
+#include "SourceBuffer.h"
+#include "SurfacePipe.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+namespace mozilla {
+namespace image {
+
+class TestSurfacePipeFactory {
+ public:
+ static SurfacePipe SimpleSurfacePipe() {
+ SurfacePipe pipe;
+ return pipe;
+ }
+
+ template <typename T>
+ static SurfacePipe SurfacePipeFromPipeline(T&& aPipeline) {
+ return SurfacePipe{std::move(aPipeline)};
+ }
+
+ private:
+ TestSurfacePipeFactory() {}
+};
+
+} // namespace image
+} // namespace mozilla
+
+void CheckSurfacePipeMethodResults(SurfacePipe* aPipe, image::Decoder* aDecoder,
+ const IntRect& aRect = IntRect(0, 0, 100,
+ 100)) {
+ // Check that the pipeline ended up in the state we expect. Note that we're
+ // explicitly testing the SurfacePipe versions of these methods, so we don't
+ // want to use AssertCorrectPipelineFinalState() here.
+ EXPECT_TRUE(aPipe->IsSurfaceFinished());
+ Maybe<SurfaceInvalidRect> invalidRect = aPipe->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isSome());
+ EXPECT_EQ(OrientedIntRect(0, 0, 100, 100), invalidRect->mInputSpaceRect);
+ EXPECT_EQ(OrientedIntRect(0, 0, 100, 100), invalidRect->mOutputSpaceRect);
+
+ // Check the generated image.
+ CheckGeneratedImage(aDecoder, aRect);
+
+ // Reset and clear the image before the next test.
+ aPipe->ResetToFirstRow();
+ EXPECT_FALSE(aPipe->IsSurfaceFinished());
+ invalidRect = aPipe->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isNothing());
+
+ uint32_t count = 0;
+ auto result = aPipe->WritePixels<uint32_t>([&]() {
+ ++count;
+ return AsVariant(BGRAColor::Transparent().AsPixel());
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u * 100u, count);
+
+ EXPECT_TRUE(aPipe->IsSurfaceFinished());
+ invalidRect = aPipe->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isSome());
+ EXPECT_EQ(OrientedIntRect(0, 0, 100, 100), invalidRect->mInputSpaceRect);
+ EXPECT_EQ(OrientedIntRect(0, 0, 100, 100), invalidRect->mOutputSpaceRect);
+
+ aPipe->ResetToFirstRow();
+ EXPECT_FALSE(aPipe->IsSurfaceFinished());
+ invalidRect = aPipe->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isNothing());
+}
+
+class ImageSurfacePipeIntegration : public ::testing::Test {
+ protected:
+ AutoInitializeImageLib mInit;
+};
+
+TEST_F(ImageSurfacePipeIntegration, SurfacePipe) {
+ // Test that SurfacePipe objects can be initialized and move constructed.
+ SurfacePipe pipe = TestSurfacePipeFactory::SimpleSurfacePipe();
+
+ // Test that SurfacePipe objects can be move assigned.
+ pipe = TestSurfacePipeFactory::SimpleSurfacePipe();
+
+ // Test that SurfacePipe objects can be initialized with a pipeline.
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ auto sink = MakeUnique<SurfaceSink>();
+ nsresult rv = sink->Configure(
+ SurfaceConfig{decoder, IntSize(100, 100), SurfaceFormat::OS_RGBA, false});
+ ASSERT_NS_SUCCEEDED(rv);
+
+ pipe = TestSurfacePipeFactory::SurfacePipeFromPipeline(sink);
+
+ // Test that WritePixels() gets passed through to the underlying pipeline.
+ {
+ uint32_t count = 0;
+ auto result = pipe.WritePixels<uint32_t>([&]() {
+ ++count;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u * 100u, count);
+ CheckSurfacePipeMethodResults(&pipe, decoder);
+ }
+
+ // Create a buffer the same size as one row of the surface, containing all
+ // green pixels. We'll use this for the WriteBuffer() tests.
+ uint32_t buffer[100];
+ for (int i = 0; i < 100; ++i) {
+ buffer[i] = BGRAColor::Green().AsPixel();
+ }
+
+ // Test that WriteBuffer() gets passed through to the underlying pipeline.
+ {
+ uint32_t count = 0;
+ WriteState result = WriteState::NEED_MORE_DATA;
+ while (result == WriteState::NEED_MORE_DATA) {
+ result = pipe.WriteBuffer(buffer);
+ ++count;
+ }
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u, count);
+ CheckSurfacePipeMethodResults(&pipe, decoder);
+ }
+
+ // Test that the 3 argument version of WriteBuffer() gets passed through to
+ // the underlying pipeline.
+ {
+ uint32_t count = 0;
+ WriteState result = WriteState::NEED_MORE_DATA;
+ while (result == WriteState::NEED_MORE_DATA) {
+ result = pipe.WriteBuffer(buffer, 0, 100);
+ ++count;
+ }
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u, count);
+ CheckSurfacePipeMethodResults(&pipe, decoder);
+ }
+
+ // Test that WritePixelBlocks() gets passed through to the underlying
+ // pipeline.
+ {
+ uint32_t count = 0;
+ WriteState result = pipe.WritePixelBlocks<uint32_t>(
+ [&](uint32_t* aBlockStart, int32_t aLength) {
+ ++count;
+ EXPECT_EQ(int32_t(100), aLength);
+ memcpy(aBlockStart, buffer, 100 * sizeof(uint32_t));
+ return std::make_tuple(int32_t(100), Maybe<WriteState>());
+ });
+
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u, count);
+ CheckSurfacePipeMethodResults(&pipe, decoder);
+ }
+
+ // Test that WriteEmptyRow() gets passed through to the underlying pipeline.
+ {
+ uint32_t count = 0;
+ WriteState result = WriteState::NEED_MORE_DATA;
+ while (result == WriteState::NEED_MORE_DATA) {
+ result = pipe.WriteEmptyRow();
+ ++count;
+ }
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u, count);
+ CheckSurfacePipeMethodResults(&pipe, decoder, IntRect(0, 0, 0, 0));
+ }
+
+ // Mark the frame as finished so we don't get an assertion.
+ RawAccessFrameRef currentFrame = decoder->GetCurrentFrameRef();
+ currentFrame->Finish();
+}
+
+TEST_F(ImageSurfacePipeIntegration, DeinterlaceDownscaleWritePixels) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ auto test = [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 25, 25)));
+ };
+
+ WithFilterPipeline(
+ decoder, test,
+ DeinterlacingConfig<uint32_t>{/* mProgressiveDisplay = */ true},
+ DownscalingConfig{IntSize(100, 100), SurfaceFormat::OS_RGBA},
+ SurfaceConfig{decoder, IntSize(25, 25), SurfaceFormat::OS_RGBA, false});
+}
+
+TEST_F(ImageSurfacePipeIntegration,
+ RemoveFrameRectBottomRightDownscaleWritePixels) {
+ // This test case uses a frame rect that extends beyond the borders of the
+ // image to the bottom and to the right. It looks roughly like this (with the
+ // box made of '#'s representing the frame rect):
+ //
+ // +------------+
+ // + +
+ // + +------------+
+ // + +############+
+ // +------+############+
+ // +############+
+ // +------------+
+
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ // Note that aInputWriteRect is 100x50 because RemoveFrameRectFilter ignores
+ // trailing rows that don't show up in the output. (Leading rows unfortunately
+ // can't be ignored.) So the action of the pipeline is as follows:
+ //
+ // (1) RemoveFrameRectFilter reads a 100x50 region of the input.
+ // (aInputWriteRect captures this fact.) The remaining 50 rows are ignored
+ // because they extend off the bottom of the image due to the frame rect's
+ // (50, 50) offset. The 50 columns on the right also don't end up in the
+ // output, so ultimately only a 50x50 region in the output contains data
+ // from the input. The filter's output is not 50x50, though, but 100x100,
+ // because what RemoveFrameRectFilter does is introduce blank rows or
+ // columns as necessary to transform an image that needs a frame rect into
+ // an image that doesn't.
+ //
+ // (2) DownscalingFilter reads the output of RemoveFrameRectFilter (100x100)
+ // and downscales it to 20x20.
+ //
+ // (3) The surface owned by SurfaceSink logically has only a 10x10 region
+ // region in it that's non-blank; this is the downscaled version of the
+ // 50x50 region discussed in (1). (aOutputWriteRect captures this fact.)
+ // Some fuzz, as usual, is necessary when dealing with Lanczos
+ // downscaling.
+
+ auto test = [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 20, 20)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(50, 50, 100, 50)),
+ /* aOutputWriteRect = */ Some(IntRect(10, 10, 10, 10)),
+ /* aFuzz = */ 0x33);
+ };
+
+ WithFilterPipeline(
+ decoder, test, RemoveFrameRectConfig{IntRect(50, 50, 100, 100)},
+ DownscalingConfig{IntSize(100, 100), SurfaceFormat::OS_RGBA},
+ SurfaceConfig{decoder, IntSize(20, 20), SurfaceFormat::OS_RGBA, false});
+}
+
+TEST_F(ImageSurfacePipeIntegration,
+ RemoveFrameRectTopLeftDownscaleWritePixels) {
+ // This test case uses a frame rect that extends beyond the borders of the
+ // image to the top and to the left. It looks roughly like this (with the
+ // box made of '#'s representing the frame rect):
+ //
+ // +------------+
+ // +############+
+ // +############+------+
+ // +############+ +
+ // +------------+ +
+ // + +
+ // +------------+
+
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ auto test = [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 20, 20)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aOutputWriteRect = */ Some(IntRect(0, 0, 10, 10)),
+ /* aFuzz = */ 0x21);
+ };
+
+ WithFilterPipeline(
+ decoder, test, RemoveFrameRectConfig{IntRect(-50, -50, 100, 100)},
+ DownscalingConfig{IntSize(100, 100), SurfaceFormat::OS_RGBA},
+ SurfaceConfig{decoder, IntSize(20, 20), SurfaceFormat::OS_RGBA, false});
+}
+
+TEST_F(ImageSurfacePipeIntegration, DeinterlaceRemoveFrameRectWritePixels) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ // Note that aInputRect is the full 100x100 size even though
+ // RemoveFrameRectFilter is part of this pipeline, because deinterlacing
+ // requires reading every row.
+
+ auto test = [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(50, 50, 100, 100)),
+ /* aOutputWriteRect = */ Some(IntRect(50, 50, 50, 50)));
+ };
+
+ WithFilterPipeline(
+ decoder, test,
+ DeinterlacingConfig<uint32_t>{/* mProgressiveDisplay = */ true},
+ RemoveFrameRectConfig{IntRect(50, 50, 100, 100)},
+ SurfaceConfig{decoder, IntSize(100, 100), SurfaceFormat::OS_RGBA, false});
+}
+
+TEST_F(ImageSurfacePipeIntegration,
+ DeinterlaceRemoveFrameRectDownscaleWritePixels) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ auto test = [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckWritePixels(aDecoder, aFilter,
+ /* aOutputRect = */ Some(IntRect(0, 0, 20, 20)),
+ /* aInputRect = */ Some(IntRect(0, 0, 100, 100)),
+ /* aInputWriteRect = */ Some(IntRect(50, 50, 100, 100)),
+ /* aOutputWriteRect = */ Some(IntRect(10, 10, 10, 10)),
+ /* aFuzz = */ 33);
+ };
+
+ WithFilterPipeline(
+ decoder, test,
+ DeinterlacingConfig<uint32_t>{/* mProgressiveDisplay = */ true},
+ RemoveFrameRectConfig{IntRect(50, 50, 100, 100)},
+ DownscalingConfig{IntSize(100, 100), SurfaceFormat::OS_RGBA},
+ SurfaceConfig{decoder, IntSize(20, 20), SurfaceFormat::OS_RGBA, false});
+}
+
+TEST_F(ImageSurfacePipeIntegration, ConfiguringHugeDeinterlacingBufferFails) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ // When DownscalingFilter is used, we may succeed in allocating an output
+ // surface for huge images, because we only need to store the scaled-down
+ // version of the image. However, regardless of downscaling,
+ // DeinterlacingFilter needs to allocate a buffer as large as the size of the
+ // input. This can cause OOMs on operating systems that allow overcommit. This
+ // test makes sure that we reject such allocations.
+ AssertConfiguringPipelineFails(
+ decoder, DeinterlacingConfig<uint32_t>{/* mProgressiveDisplay = */ true},
+ DownscalingConfig{IntSize(60000, 60000), SurfaceFormat::OS_RGBA},
+ SurfaceConfig{decoder, IntSize(600, 600), SurfaceFormat::OS_RGBA, false});
+}
diff --git a/image/test/gtest/TestSurfaceSink.cpp b/image/test/gtest/TestSurfaceSink.cpp
new file mode 100644
index 0000000000..b205f00e7f
--- /dev/null
+++ b/image/test/gtest/TestSurfaceSink.cpp
@@ -0,0 +1,982 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "mozilla/gfx/2D.h"
+#include "Common.h"
+#include "Decoder.h"
+#include "DecoderFactory.h"
+#include "SourceBuffer.h"
+#include "SurfacePipe.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+enum class Orient { NORMAL, FLIP_VERTICALLY };
+
+static void InitializeRowBuffer(uint32_t* aBuffer, size_t aSize,
+ size_t aStartPixel, size_t aEndPixel,
+ uint32_t aSetPixel) {
+ uint32_t transparentPixel = BGRAColor::Transparent().AsPixel();
+ for (size_t i = 0; i < aStartPixel && i < aSize; ++i) {
+ aBuffer[i] = transparentPixel;
+ }
+ for (size_t i = aStartPixel; i < aEndPixel && i < aSize; ++i) {
+ aBuffer[i] = aSetPixel;
+ }
+ for (size_t i = aEndPixel; i < aSize; ++i) {
+ aBuffer[i] = transparentPixel;
+ }
+}
+
+template <Orient Orientation, typename Func>
+void WithSurfaceSink(Func aFunc) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ const bool flipVertically = Orientation == Orient::FLIP_VERTICALLY;
+
+ WithFilterPipeline(decoder, std::forward<Func>(aFunc),
+ SurfaceConfig{decoder, IntSize(100, 100),
+ SurfaceFormat::OS_RGBA, flipVertically});
+}
+
+void ResetForNextPass(SurfaceFilter* aSink) {
+ aSink->ResetToFirstRow();
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+ Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isNothing());
+}
+
+template <typename WriteFunc, typename CheckFunc>
+void DoCheckIterativeWrite(SurfaceFilter* aSink, WriteFunc aWriteFunc,
+ CheckFunc aCheckFunc) {
+ // Write the buffer to successive rows until every row of the surface
+ // has been written.
+ uint32_t row = 0;
+ WriteState result = WriteState::NEED_MORE_DATA;
+ while (result == WriteState::NEED_MORE_DATA) {
+ result = aWriteFunc(row);
+ ++row;
+ }
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u, row);
+
+ AssertCorrectPipelineFinalState(aSink, IntRect(0, 0, 100, 100),
+ IntRect(0, 0, 100, 100));
+
+ // Check that the generated image is correct.
+ aCheckFunc();
+}
+
+template <typename WriteFunc>
+void CheckIterativeWrite(image::Decoder* aDecoder, SurfaceSink* aSink,
+ const IntRect& aOutputRect, WriteFunc aWriteFunc) {
+ // Ignore the row passed to WriteFunc, since no callers use it.
+ auto writeFunc = [&](uint32_t) { return aWriteFunc(); };
+
+ DoCheckIterativeWrite(aSink, writeFunc,
+ [&] { CheckGeneratedImage(aDecoder, aOutputRect); });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkInitialization)
+{
+ WithSurfaceSink<Orient::NORMAL>(
+ [](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ // Check initial state.
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+ Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isNothing());
+
+ // Check that the surface is zero-initialized. We verify this by calling
+ // CheckGeneratedImage() and telling it that we didn't write to the
+ // surface anyway (i.e., we wrote to the empty rect); it will then
+ // expect the entire surface to be transparent, which is what it should
+ // be if it was zero-initialied.
+ CheckGeneratedImage(aDecoder, IntRect(0, 0, 0, 0));
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWritePixels)
+{
+ WithSurfaceSink<Orient::NORMAL>(
+ [](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ CheckWritePixels(aDecoder, aSink);
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWritePixelsFinish)
+{
+ WithSurfaceSink<Orient::NORMAL>(
+ [](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ // Write nothing into the surface; just finish immediately.
+ uint32_t count = 0;
+ auto result = aSink->WritePixels<uint32_t>([&]() {
+ count++;
+ return AsVariant(WriteState::FINISHED);
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(1u, count);
+
+ AssertCorrectPipelineFinalState(aSink, IntRect(0, 0, 100, 100),
+ IntRect(0, 0, 100, 100));
+
+ // Attempt to write more and make sure that nothing gets written.
+ count = 0;
+ result = aSink->WritePixels<uint32_t>([&]() {
+ count++;
+ return AsVariant(BGRAColor::Red().AsPixel());
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(0u, count);
+ EXPECT_TRUE(aSink->IsSurfaceFinished());
+
+ // Check that the generated image is correct.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Transparent()));
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWritePixelsEarlyExit)
+{
+ auto checkEarlyExit = [](image::Decoder* aDecoder, SurfaceSink* aSink,
+ WriteState aState) {
+ // Write half a row of green pixels and then exit early with |aState|. If
+ // the lambda keeps getting called, we'll write red pixels, which will cause
+ // the test to fail.
+ uint32_t count = 0;
+ auto result = aSink->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
+ if (count == 50) {
+ return AsVariant(aState);
+ }
+ return count++ < 50 ? AsVariant(BGRAColor::Green().AsPixel())
+ : AsVariant(BGRAColor::Red().AsPixel());
+ });
+
+ EXPECT_EQ(aState, result);
+ EXPECT_EQ(50u, count);
+ CheckGeneratedImage(aDecoder, IntRect(0, 0, 50, 1));
+
+ if (aState != WriteState::FINISHED) {
+ // We should still be able to write more at this point.
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+
+ // Verify that we can resume writing. We'll finish up the same row.
+ count = 0;
+ result = aSink->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
+ if (count == 50) {
+ return AsVariant(WriteState::NEED_MORE_DATA);
+ }
+ ++count;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+
+ EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
+ EXPECT_EQ(50u, count);
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+ CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, 1));
+
+ return;
+ }
+
+ // We should've finished the surface at this point.
+ AssertCorrectPipelineFinalState(aSink, IntRect(0, 0, 100, 100),
+ IntRect(0, 0, 100, 100));
+
+ // Attempt to write more and make sure that nothing gets written.
+ count = 0;
+ result = aSink->WritePixels<uint32_t>([&] {
+ count++;
+ return AsVariant(BGRAColor::Red().AsPixel());
+ });
+
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(0u, count);
+ EXPECT_TRUE(aSink->IsSurfaceFinished());
+
+ // Check that the generated image is still correct.
+ CheckGeneratedImage(aDecoder, IntRect(0, 0, 50, 1));
+ };
+
+ WithSurfaceSink<Orient::NORMAL>(
+ [&](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ checkEarlyExit(aDecoder, aSink, WriteState::NEED_MORE_DATA);
+ });
+
+ WithSurfaceSink<Orient::NORMAL>(
+ [&](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ checkEarlyExit(aDecoder, aSink, WriteState::FAILURE);
+ });
+
+ WithSurfaceSink<Orient::NORMAL>(
+ [&](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ checkEarlyExit(aDecoder, aSink, WriteState::FINISHED);
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWritePixelsToRow)
+{
+ WithSurfaceSink<Orient::NORMAL>([](image::Decoder* aDecoder,
+ SurfaceSink* aSink) {
+ // Write the first 99 rows of our 100x100 surface and verify that even
+ // though our lambda will yield pixels forever, only one row is written
+ // per call to WritePixelsToRow().
+ for (int row = 0; row < 99; ++row) {
+ uint32_t count = 0;
+ WriteState result = aSink->WritePixelsToRow<uint32_t>([&] {
+ ++count;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+
+ EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
+ EXPECT_EQ(100u, count);
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+
+ Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isSome());
+ EXPECT_EQ(OrientedIntRect(0, row, 100, 1), invalidRect->mInputSpaceRect);
+ EXPECT_EQ(OrientedIntRect(0, row, 100, 1), invalidRect->mOutputSpaceRect);
+
+ CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, row + 1));
+ }
+
+ // Write the final line, which should finish the surface.
+ uint32_t count = 0;
+ WriteState result = aSink->WritePixelsToRow<uint32_t>([&] {
+ ++count;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u, count);
+
+ // Note that the final invalid rect we expect here is only the last row;
+ // that's because we called TakeInvalidRect() repeatedly in the loop
+ // above.
+ AssertCorrectPipelineFinalState(aSink, IntRect(0, 99, 100, 1),
+ IntRect(0, 99, 100, 1));
+
+ // Check that the generated image is correct.
+ CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, 100));
+
+ // Attempt to write more and make sure that nothing gets written.
+ count = 0;
+ result = aSink->WritePixelsToRow<uint32_t>([&] {
+ count++;
+ return AsVariant(BGRAColor::Red().AsPixel());
+ });
+
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(0u, count);
+ EXPECT_TRUE(aSink->IsSurfaceFinished());
+
+ // Check that the generated image is still correct.
+ CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, 100));
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWritePixelsToRowEarlyExit)
+{
+ auto checkEarlyExit = [](image::Decoder* aDecoder, SurfaceSink* aSink,
+ WriteState aState) {
+ // Write half a row of green pixels and then exit early with |aState|. If
+ // the lambda keeps getting called, we'll write red pixels, which will cause
+ // the test to fail.
+ uint32_t count = 0;
+ auto result =
+ aSink->WritePixelsToRow<uint32_t>([&]() -> NextPixel<uint32_t> {
+ if (count == 50) {
+ return AsVariant(aState);
+ }
+ return count++ < 50 ? AsVariant(BGRAColor::Green().AsPixel())
+ : AsVariant(BGRAColor::Red().AsPixel());
+ });
+
+ EXPECT_EQ(aState, result);
+ EXPECT_EQ(50u, count);
+ CheckGeneratedImage(aDecoder, IntRect(0, 0, 50, 1));
+
+ if (aState != WriteState::FINISHED) {
+ // We should still be able to write more at this point.
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+
+ // Verify that we can resume the same row and still stop at the end.
+ count = 0;
+ WriteState result = aSink->WritePixelsToRow<uint32_t>([&] {
+ ++count;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+
+ EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
+ EXPECT_EQ(50u, count);
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+ CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, 1));
+
+ return;
+ }
+
+ // We should've finished the surface at this point.
+ AssertCorrectPipelineFinalState(aSink, IntRect(0, 0, 100, 100),
+ IntRect(0, 0, 100, 100));
+
+ // Attempt to write more and make sure that nothing gets written.
+ count = 0;
+ result = aSink->WritePixelsToRow<uint32_t>([&] {
+ count++;
+ return AsVariant(BGRAColor::Red().AsPixel());
+ });
+
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(0u, count);
+ EXPECT_TRUE(aSink->IsSurfaceFinished());
+
+ // Check that the generated image is still correct.
+ CheckGeneratedImage(aDecoder, IntRect(0, 0, 50, 1));
+ };
+
+ WithSurfaceSink<Orient::NORMAL>(
+ [&](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ checkEarlyExit(aDecoder, aSink, WriteState::NEED_MORE_DATA);
+ });
+
+ WithSurfaceSink<Orient::NORMAL>(
+ [&](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ checkEarlyExit(aDecoder, aSink, WriteState::FAILURE);
+ });
+
+ WithSurfaceSink<Orient::NORMAL>(
+ [&](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ checkEarlyExit(aDecoder, aSink, WriteState::FINISHED);
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWriteBuffer)
+{
+ WithSurfaceSink<Orient::NORMAL>(
+ [](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ // Create a green buffer the same size as one row of the surface (which
+ // is 100x100), containing 60 pixels of green in the middle and 20
+ // transparent pixels on either side.
+ uint32_t buffer[100];
+ InitializeRowBuffer(buffer, 100, 20, 80, BGRAColor::Green().AsPixel());
+
+ // Write the buffer to every row of the surface and check that the
+ // generated image is correct.
+ CheckIterativeWrite(aDecoder, aSink, IntRect(20, 0, 60, 100),
+ [&] { return aSink->WriteBuffer(buffer); });
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWriteBufferPartialRow)
+{
+ WithSurfaceSink<Orient::NORMAL>(
+ [](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ // Create a buffer the same size as one row of the surface, containing
+ // all green pixels.
+ uint32_t buffer[100];
+ for (int i = 0; i < 100; ++i) {
+ buffer[i] = BGRAColor::Green().AsPixel();
+ }
+
+ // Write the buffer to the middle 60 pixels of every row of the surface
+ // and check that the generated image is correct.
+ CheckIterativeWrite(aDecoder, aSink, IntRect(20, 0, 60, 100),
+ [&] { return aSink->WriteBuffer(buffer, 20, 60); });
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWriteBufferPartialRowStartColOverflow)
+{
+ WithSurfaceSink<Orient::NORMAL>([](image::Decoder* aDecoder,
+ SurfaceSink* aSink) {
+ // Create a buffer the same size as one row of the surface, containing all
+ // green pixels.
+ uint32_t buffer[100];
+ for (int i = 0; i < 100; ++i) {
+ buffer[i] = BGRAColor::Green().AsPixel();
+ }
+
+ {
+ // Write the buffer to successive rows until every row of the surface
+ // has been written. We place the start column beyond the end of the row,
+ // which will prevent us from writing anything, so we check that the
+ // generated image is entirely transparent.
+ CheckIterativeWrite(aDecoder, aSink, IntRect(0, 0, 0, 0),
+ [&] { return aSink->WriteBuffer(buffer, 100, 100); });
+ }
+
+ ResetForNextPass(aSink);
+
+ {
+ // Write the buffer to successive rows until every row of the surface
+ // has been written. We use column 50 as the start column, but we still
+ // write the buffer, which means we overflow the right edge of the surface
+ // by 50 pixels. We check that the left half of the generated image is
+ // transparent and the right half is green.
+ CheckIterativeWrite(aDecoder, aSink, IntRect(50, 0, 50, 100),
+ [&] { return aSink->WriteBuffer(buffer, 50, 100); });
+ }
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWriteBufferPartialRowBufferOverflow)
+{
+ WithSurfaceSink<Orient::NORMAL>([](image::Decoder* aDecoder,
+ SurfaceSink* aSink) {
+ // Create a buffer twice as large as a row of the surface. The first half
+ // (which is as large as a row of the image) will contain green pixels,
+ // while the second half will contain red pixels.
+ uint32_t buffer[200];
+ for (int i = 0; i < 200; ++i) {
+ buffer[i] =
+ i < 100 ? BGRAColor::Green().AsPixel() : BGRAColor::Red().AsPixel();
+ }
+
+ {
+ // Write the buffer to successive rows until every row of the surface has
+ // been written. The buffer extends 100 pixels to the right of a row of
+ // the surface, but bounds checking will prevent us from overflowing the
+ // buffer. We check that the generated image is entirely green since the
+ // pixels on the right side of the buffer shouldn't have been written to
+ // the surface.
+ CheckIterativeWrite(aDecoder, aSink, IntRect(0, 0, 100, 100),
+ [&] { return aSink->WriteBuffer(buffer, 0, 200); });
+ }
+
+ ResetForNextPass(aSink);
+
+ {
+ // Write from the buffer to the middle of each row of the surface. That
+ // means that the left side of each row should be transparent, since we
+ // didn't write anything there. A buffer overflow would cause us to write
+ // buffer contents into the left side of each row. We check that the
+ // generated image is transparent on the left side and green on the right.
+ CheckIterativeWrite(aDecoder, aSink, IntRect(50, 0, 50, 100),
+ [&] { return aSink->WriteBuffer(buffer, 50, 200); });
+ }
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWriteBufferFromNullSource)
+{
+ WithSurfaceSink<Orient::NORMAL>(
+ [](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ // Calling WriteBuffer() with a null pointer should fail without making
+ // any changes to the surface.
+ uint32_t* nullBuffer = nullptr;
+ WriteState result = aSink->WriteBuffer(nullBuffer);
+
+ EXPECT_EQ(WriteState::FAILURE, result);
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+ Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isNothing());
+
+ // Check that nothing got written to the surface.
+ CheckGeneratedImage(aDecoder, IntRect(0, 0, 0, 0));
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWriteEmptyRow)
+{
+ WithSurfaceSink<Orient::NORMAL>([](image::Decoder* aDecoder,
+ SurfaceSink* aSink) {
+ {
+ // Write an empty row to each row of the surface. We check that the
+ // generated image is entirely transparent.
+ CheckIterativeWrite(aDecoder, aSink, IntRect(0, 0, 0, 0),
+ [&] { return aSink->WriteEmptyRow(); });
+ }
+
+ ResetForNextPass(aSink);
+
+ {
+ // Write a partial row before we begin calling WriteEmptyRow(). We check
+ // that the generated image is entirely transparent, which is to be
+ // expected since WriteEmptyRow() overwrites the current row even if some
+ // data has already been written to it.
+ uint32_t count = 0;
+ auto result = aSink->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
+ if (count == 50) {
+ return AsVariant(WriteState::NEED_MORE_DATA);
+ }
+ ++count;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+
+ EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
+ EXPECT_EQ(50u, count);
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+
+ CheckIterativeWrite(aDecoder, aSink, IntRect(0, 0, 0, 0),
+ [&] { return aSink->WriteEmptyRow(); });
+ }
+
+ ResetForNextPass(aSink);
+
+ {
+ // Create a buffer the same size as one row of the surface, containing all
+ // green pixels.
+ uint32_t buffer[100];
+ for (int i = 0; i < 100; ++i) {
+ buffer[i] = BGRAColor::Green().AsPixel();
+ }
+
+ // Write an empty row to the middle 60 rows of the surface. The first 20
+ // and last 20 rows will be green. (We need to use DoCheckIterativeWrite()
+ // here because we need a custom function to check the output, since it
+ // can't be described by a simple rect.)
+ auto writeFunc = [&](uint32_t aRow) {
+ if (aRow < 20 || aRow >= 80) {
+ return aSink->WriteBuffer(buffer);
+ } else {
+ return aSink->WriteEmptyRow();
+ }
+ };
+
+ auto checkFunc = [&] {
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 20, BGRAColor::Green()));
+ EXPECT_TRUE(
+ RowsAreSolidColor(surface, 20, 60, BGRAColor::Transparent()));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 80, 20, BGRAColor::Green()));
+ };
+
+ DoCheckIterativeWrite(aSink, writeFunc, checkFunc);
+ }
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWriteUnsafeComputedRow)
+{
+ WithSurfaceSink<Orient::NORMAL>(
+ [](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ // Create a green buffer the same size as one row of the surface.
+ uint32_t buffer[100];
+ for (int i = 0; i < 100; ++i) {
+ buffer[i] = BGRAColor::Green().AsPixel();
+ }
+
+ // Write the buffer to successive rows until every row of the surface
+ // has been written. We only write to the right half of each row, so we
+ // check that the left side of the generated image is transparent and
+ // the right side is green.
+ CheckIterativeWrite(aDecoder, aSink, IntRect(50, 0, 50, 100), [&] {
+ return aSink->WriteUnsafeComputedRow<uint32_t>(
+ [&](uint32_t* aRow, uint32_t aLength) {
+ EXPECT_EQ(100u, aLength);
+ memcpy(aRow + 50, buffer, 50 * sizeof(uint32_t));
+ });
+ });
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWritePixelBlocks)
+{
+ WithSurfaceSink<Orient::NORMAL>(
+ [](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ // Create a green buffer the same size as one row of the surface (which
+ // is 100x100), containing 60 pixels of green in the middle and 20
+ // transparent pixels on either side.
+ uint32_t buffer[100];
+ InitializeRowBuffer(buffer, 100, 20, 80, BGRAColor::Green().AsPixel());
+
+ uint32_t count = 0;
+ WriteState result = aSink->WritePixelBlocks<uint32_t>(
+ [&](uint32_t* aBlockStart, int32_t aLength) {
+ ++count;
+ EXPECT_EQ(int32_t(100), aLength);
+ memcpy(aBlockStart, buffer, 100 * sizeof(uint32_t));
+ return std::make_tuple(int32_t(100), Maybe<WriteState>());
+ });
+
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u, count);
+
+ AssertCorrectPipelineFinalState(aSink, IntRect(0, 0, 100, 100),
+ IntRect(0, 0, 100, 100));
+
+ // Check that the generated image is correct.
+ CheckGeneratedImage(aDecoder, IntRect(20, 0, 60, 100));
+
+ // Attempt to write more and make sure that nothing gets written.
+ count = 0;
+ result = aSink->WritePixelBlocks<uint32_t>(
+ [&](uint32_t* aBlockStart, int32_t aLength) {
+ count++;
+ for (int32_t i = 0; i < aLength; ++i) {
+ aBlockStart[i] = BGRAColor::Red().AsPixel();
+ }
+ return std::make_tuple(aLength, Maybe<WriteState>());
+ });
+
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(0u, count);
+ EXPECT_TRUE(aSink->IsSurfaceFinished());
+
+ // Check that the generated image is still correct.
+ CheckGeneratedImage(aDecoder, IntRect(20, 0, 60, 100));
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkWritePixelBlocksPartialRow)
+{
+ WithSurfaceSink<Orient::NORMAL>([](image::Decoder* aDecoder,
+ SurfaceSink* aSink) {
+ // Create a green buffer the same size as one row of the surface (which is
+ // 100x100), containing 60 pixels of green in the middle and 20 transparent
+ // pixels on either side.
+ uint32_t buffer[100];
+ InitializeRowBuffer(buffer, 100, 20, 80, BGRAColor::Green().AsPixel());
+
+ // Write the first 99 rows of our 100x100 surface and verify that even
+ // though our lambda will yield pixels forever, only one row is written per
+ // call to WritePixelsToRow().
+ for (int row = 0; row < 99; ++row) {
+ for (int32_t written = 0; written < 100;) {
+ WriteState result = aSink->WritePixelBlocks<uint32_t>(
+ [&](uint32_t* aBlockStart, int32_t aLength) {
+ // When we write the final block of pixels, it will request we
+ // start another row. We should abort at that point.
+ if (aLength == int32_t(100) && written == int32_t(100)) {
+ return std::make_tuple(int32_t(0),
+ Some(WriteState::NEED_MORE_DATA));
+ }
+
+ // It should always request enough data to fill the row. So it
+ // should request 100, 75, 50, and finally 25 pixels.
+ EXPECT_EQ(int32_t(100) - written, aLength);
+
+ // Only write one quarter of the pixels for the row.
+ memcpy(aBlockStart, &buffer[written], 25 * sizeof(uint32_t));
+ written += 25;
+
+ // We've written the last pixels remaining for the row.
+ if (written == int32_t(100)) {
+ return std::make_tuple(int32_t(25), Maybe<WriteState>());
+ }
+
+ // We've written another quarter of the row but not yet all of it.
+ return std::make_tuple(int32_t(25),
+ Some(WriteState::NEED_MORE_DATA));
+ });
+
+ EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
+ }
+
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+
+ Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isSome());
+ EXPECT_EQ(OrientedIntRect(0, row, 100, 1), invalidRect->mInputSpaceRect);
+ EXPECT_EQ(OrientedIntRect(0, row, 100, 1), invalidRect->mOutputSpaceRect);
+
+ CheckGeneratedImage(aDecoder, IntRect(20, 0, 60, row + 1));
+ }
+
+ // Write the final line, which should finish the surface.
+ uint32_t count = 0;
+ WriteState result = aSink->WritePixelBlocks<uint32_t>(
+ [&](uint32_t* aBlockStart, int32_t aLength) {
+ ++count;
+ EXPECT_EQ(int32_t(100), aLength);
+ memcpy(aBlockStart, buffer, 100 * sizeof(uint32_t));
+ return std::make_tuple(int32_t(100), Maybe<WriteState>());
+ });
+
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(1u, count);
+
+ // Note that the final invalid rect we expect here is only the last row;
+ // that's because we called TakeInvalidRect() repeatedly in the loop above.
+ AssertCorrectPipelineFinalState(aSink, IntRect(0, 99, 100, 1),
+ IntRect(0, 99, 100, 1));
+
+ // Check that the generated image is correct.
+ CheckGeneratedImage(aDecoder, IntRect(20, 0, 60, 100));
+
+ // Attempt to write more and make sure that nothing gets written.
+ count = 0;
+ result = aSink->WritePixelBlocks<uint32_t>(
+ [&](uint32_t* aBlockStart, int32_t aLength) {
+ count++;
+ for (int32_t i = 0; i < aLength; ++i) {
+ aBlockStart[i] = BGRAColor::Red().AsPixel();
+ }
+ return std::make_tuple(aLength, Maybe<WriteState>());
+ });
+
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(0u, count);
+ EXPECT_TRUE(aSink->IsSurfaceFinished());
+
+ // Check that the generated image is still correct.
+ CheckGeneratedImage(aDecoder, IntRect(20, 0, 60, 100));
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkProgressivePasses)
+{
+ WithSurfaceSink<Orient::NORMAL>(
+ [](image::Decoder* aDecoder, SurfaceSink* aSink) {
+ {
+ // Fill the image with a first pass of red.
+ uint32_t count = 0;
+ auto result = aSink->WritePixels<uint32_t>([&]() {
+ ++count;
+ return AsVariant(BGRAColor::Red().AsPixel());
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u * 100u, count);
+
+ AssertCorrectPipelineFinalState(aSink, IntRect(0, 0, 100, 100),
+ IntRect(0, 0, 100, 100));
+
+ // Check that the generated image is correct.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Red()));
+ }
+
+ {
+ ResetForNextPass(aSink);
+
+ // Check that the generated image is still the first pass image.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Red()));
+ }
+
+ {
+ // Fill the image with a second pass of green.
+ uint32_t count = 0;
+ auto result = aSink->WritePixels<uint32_t>([&]() {
+ ++count;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u * 100u, count);
+
+ AssertCorrectPipelineFinalState(aSink, IntRect(0, 0, 100, 100),
+ IntRect(0, 0, 100, 100));
+
+ // Check that the generated image is correct.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Green()));
+ }
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkInvalidRect)
+{
+ WithSurfaceSink<Orient::NORMAL>([](image::Decoder* aDecoder,
+ SurfaceSink* aSink) {
+ {
+ // Write one row.
+ uint32_t count = 0;
+ auto result = aSink->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
+ if (count == 100) {
+ return AsVariant(WriteState::NEED_MORE_DATA);
+ }
+ count++;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+ EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
+ EXPECT_EQ(100u, count);
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+
+ // Assert that we have the right invalid rect.
+ Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isSome());
+ EXPECT_EQ(OrientedIntRect(0, 0, 100, 1), invalidRect->mInputSpaceRect);
+ EXPECT_EQ(OrientedIntRect(0, 0, 100, 1), invalidRect->mOutputSpaceRect);
+ }
+
+ {
+ // Write eight rows.
+ uint32_t count = 0;
+ auto result = aSink->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
+ if (count == 100 * 8) {
+ return AsVariant(WriteState::NEED_MORE_DATA);
+ }
+ count++;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+ EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
+ EXPECT_EQ(100u * 8u, count);
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+
+ // Assert that we have the right invalid rect.
+ Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isSome());
+ EXPECT_EQ(OrientedIntRect(0, 1, 100, 8), invalidRect->mInputSpaceRect);
+ EXPECT_EQ(OrientedIntRect(0, 1, 100, 8), invalidRect->mOutputSpaceRect);
+ }
+
+ {
+ // Write the left half of one row.
+ uint32_t count = 0;
+ auto result = aSink->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
+ if (count == 50) {
+ return AsVariant(WriteState::NEED_MORE_DATA);
+ }
+ count++;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+ EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
+ EXPECT_EQ(50u, count);
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+
+ // Assert that we don't have an invalid rect, since the invalid rect only
+ // gets updated when a row gets completed.
+ Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isNothing());
+ }
+
+ {
+ // Write the right half of the same row.
+ uint32_t count = 0;
+ auto result = aSink->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
+ if (count == 50) {
+ return AsVariant(WriteState::NEED_MORE_DATA);
+ }
+ count++;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+ EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
+ EXPECT_EQ(50u, count);
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+
+ // Assert that we have the right invalid rect, which will include both the
+ // left and right halves of this row now that we've completed it.
+ Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isSome());
+ EXPECT_EQ(OrientedIntRect(0, 9, 100, 1), invalidRect->mInputSpaceRect);
+ EXPECT_EQ(OrientedIntRect(0, 9, 100, 1), invalidRect->mOutputSpaceRect);
+ }
+
+ {
+ // Write no rows.
+ auto result = aSink->WritePixels<uint32_t>(
+ [&]() { return AsVariant(WriteState::NEED_MORE_DATA); });
+ EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+
+ // Assert that we don't have an invalid rect.
+ Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isNothing());
+ }
+
+ {
+ // Fill the rest of the image.
+ uint32_t count = 0;
+ auto result = aSink->WritePixels<uint32_t>([&]() {
+ count++;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u * 90u, count);
+ EXPECT_TRUE(aSink->IsSurfaceFinished());
+
+ // Assert that we have the right invalid rect.
+ Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isSome());
+ EXPECT_EQ(OrientedIntRect(0, 10, 100, 90), invalidRect->mInputSpaceRect);
+ EXPECT_EQ(OrientedIntRect(0, 10, 100, 90), invalidRect->mOutputSpaceRect);
+
+ // Check that the generated image is correct.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Green()));
+ }
+ });
+}
+
+TEST(ImageSurfaceSink, SurfaceSinkFlipVertically)
+{
+ WithSurfaceSink<Orient::FLIP_VERTICALLY>([](image::Decoder* aDecoder,
+ SurfaceSink* aSink) {
+ {
+ // Fill the image with a first pass of red.
+ uint32_t count = 0;
+ auto result = aSink->WritePixels<uint32_t>([&]() {
+ ++count;
+ return AsVariant(BGRAColor::Red().AsPixel());
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(100u * 100u, count);
+
+ AssertCorrectPipelineFinalState(aSink, IntRect(0, 0, 100, 100),
+ IntRect(0, 0, 100, 100));
+
+ // Check that the generated image is correct.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Red()));
+ }
+
+ {
+ ResetForNextPass(aSink);
+
+ // Check that the generated image is still the first pass image.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Red()));
+ }
+
+ {
+ // Fill 25 rows of the image with green and make sure everything is OK.
+ uint32_t count = 0;
+ auto result = aSink->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
+ if (count == 25 * 100) {
+ return AsVariant(WriteState::NEED_MORE_DATA);
+ }
+ count++;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+ EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
+ EXPECT_EQ(25u * 100u, count);
+ EXPECT_FALSE(aSink->IsSurfaceFinished());
+
+ // Assert that we have the right invalid rect, which should include the
+ // *bottom* (since we're flipping vertically) 25 rows of the image.
+ Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
+ EXPECT_TRUE(invalidRect.isSome());
+ EXPECT_EQ(OrientedIntRect(0, 75, 100, 25), invalidRect->mInputSpaceRect);
+ EXPECT_EQ(OrientedIntRect(0, 75, 100, 25), invalidRect->mOutputSpaceRect);
+
+ // Check that the generated image is correct.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ EXPECT_TRUE(RowsAreSolidColor(surface, 0, 75, BGRAColor::Red()));
+ EXPECT_TRUE(RowsAreSolidColor(surface, 75, 25, BGRAColor::Green()));
+ }
+
+ {
+ // Fill the rest of the image with a second pass of green.
+ uint32_t count = 0;
+ auto result = aSink->WritePixels<uint32_t>([&]() {
+ ++count;
+ return AsVariant(BGRAColor::Green().AsPixel());
+ });
+ EXPECT_EQ(WriteState::FINISHED, result);
+ EXPECT_EQ(75u * 100u, count);
+
+ AssertCorrectPipelineFinalState(aSink, IntRect(0, 0, 100, 75),
+ IntRect(0, 0, 100, 75));
+
+ // Check that the generated image is correct.
+ RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+ RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
+ EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Green()));
+ }
+ });
+}
diff --git a/image/test/gtest/TestSwizzleFilter.cpp b/image/test/gtest/TestSwizzleFilter.cpp
new file mode 100644
index 0000000000..65faf85155
--- /dev/null
+++ b/image/test/gtest/TestSwizzleFilter.cpp
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "mozilla/gfx/2D.h"
+#include "Common.h"
+#include "Decoder.h"
+#include "DecoderFactory.h"
+#include "SurfaceFilters.h"
+#include "SurfacePipe.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+template <typename Func>
+void WithSwizzleFilter(const IntSize& aSize, SurfaceFormat aInputFormat,
+ SurfaceFormat aOutputFormat, bool aPremultiplyAlpha,
+ Func aFunc) {
+ RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
+ ASSERT_TRUE(decoder != nullptr);
+
+ WithFilterPipeline(
+ decoder, std::forward<Func>(aFunc),
+ SwizzleConfig{aInputFormat, aOutputFormat, aPremultiplyAlpha},
+ SurfaceConfig{decoder, aSize, aOutputFormat, false});
+}
+
+TEST(ImageSwizzleFilter, WritePixels_RGBA_to_BGRA)
+{
+ WithSwizzleFilter(
+ IntSize(100, 100), SurfaceFormat::R8G8B8A8, SurfaceFormat::B8G8R8A8,
+ false, [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckTransformedWritePixels(aDecoder, aFilter, BGRAColor::Blue(),
+ BGRAColor::Red());
+ });
+}
+
+TEST(ImageSwizzleFilter, WritePixels_RGBA_to_Premultiplied_BGRA)
+{
+ WithSwizzleFilter(
+ IntSize(100, 100), SurfaceFormat::R8G8B8A8, SurfaceFormat::B8G8R8A8, true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckTransformedWritePixels(
+ aDecoder, aFilter, BGRAColor(0x26, 0x00, 0x00, 0x7F, true),
+ BGRAColor(0x00, 0x00, 0x26, 0x7F), Nothing(), Nothing(), Nothing(),
+ Nothing(), /* aFuzz */ 1);
+ });
+}
+
+TEST(ImageSwizzleFilter, WritePixels_RGBA_to_BGRX)
+{
+ WithSwizzleFilter(
+ IntSize(100, 100), SurfaceFormat::R8G8B8A8, SurfaceFormat::B8G8R8X8,
+ false, [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckTransformedWritePixels(aDecoder, aFilter,
+ BGRAColor(0x26, 0x00, 0x00, 0x7F, true),
+ BGRAColor(0x00, 0x00, 0x26, 0xFF));
+ });
+}
+
+TEST(ImageSwizzleFilter, WritePixels_RGBA_to_Premultiplied_BGRX)
+{
+ WithSwizzleFilter(
+ IntSize(100, 100), SurfaceFormat::R8G8B8A8, SurfaceFormat::B8G8R8X8, true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckTransformedWritePixels(aDecoder, aFilter,
+ BGRAColor(0x26, 0x00, 0x00, 0x7F, true),
+ BGRAColor(0x00, 0x00, 0x13, 0xFF));
+ });
+}
+
+TEST(ImageSwizzleFilter, WritePixels_RGBA_to_RGBX)
+{
+ WithSwizzleFilter(
+ IntSize(100, 100), SurfaceFormat::R8G8B8A8, SurfaceFormat::R8G8B8X8,
+ false, [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckTransformedWritePixels(aDecoder, aFilter,
+ BGRAColor(0x00, 0x00, 0x26, 0x7F, true),
+ BGRAColor(0x00, 0x00, 0x26, 0xFF));
+ });
+}
+
+TEST(ImageSwizzleFilter, WritePixels_RGBA_to_Premultiplied_RGRX)
+{
+ WithSwizzleFilter(
+ IntSize(100, 100), SurfaceFormat::R8G8B8A8, SurfaceFormat::R8G8B8X8, true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckTransformedWritePixels(aDecoder, aFilter,
+ BGRAColor(0x00, 0x00, 0x26, 0x7F, true),
+ BGRAColor(0x00, 0x00, 0x13, 0xFF));
+ });
+}
+
+TEST(ImageSwizzleFilter, WritePixels_BGRA_to_BGRX)
+{
+ WithSwizzleFilter(
+ IntSize(100, 100), SurfaceFormat::B8G8R8A8, SurfaceFormat::B8G8R8X8,
+ false, [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckTransformedWritePixels(aDecoder, aFilter,
+ BGRAColor(0x10, 0x26, 0x00, 0x7F, true),
+ BGRAColor(0x10, 0x26, 0x00, 0xFF));
+ });
+}
+
+TEST(ImageSwizzleFilter, WritePixels_BGRA_to_Premultiplied_BGRA)
+{
+ WithSwizzleFilter(
+ IntSize(100, 100), SurfaceFormat::B8G8R8A8, SurfaceFormat::B8G8R8A8, true,
+ [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
+ CheckTransformedWritePixels(
+ aDecoder, aFilter, BGRAColor(0x10, 0x26, 0x00, 0x7F, true),
+ BGRAColor(0x10, 0x26, 0x00, 0x7F), Nothing(), Nothing(), Nothing(),
+ Nothing(), /* aFuzz */ 1);
+ });
+}
diff --git a/image/test/gtest/animated-with-extra-image-sub-blocks.gif b/image/test/gtest/animated-with-extra-image-sub-blocks.gif
new file mode 100644
index 0000000000..a145c814a6
--- /dev/null
+++ b/image/test/gtest/animated-with-extra-image-sub-blocks.gif
Binary files differ
diff --git a/image/test/gtest/blend.avif b/image/test/gtest/blend.avif
new file mode 100644
index 0000000000..f059f04d10
--- /dev/null
+++ b/image/test/gtest/blend.avif
Binary files differ
diff --git a/image/test/gtest/blend.gif b/image/test/gtest/blend.gif
new file mode 100644
index 0000000000..2f7391454c
--- /dev/null
+++ b/image/test/gtest/blend.gif
Binary files differ
diff --git a/image/test/gtest/blend.png b/image/test/gtest/blend.png
new file mode 100644
index 0000000000..c4e739f068
--- /dev/null
+++ b/image/test/gtest/blend.png
Binary files differ
diff --git a/image/test/gtest/blend.webp b/image/test/gtest/blend.webp
new file mode 100644
index 0000000000..1b95e6f377
--- /dev/null
+++ b/image/test/gtest/blend.webp
Binary files differ
diff --git a/image/test/gtest/bug-1655846.avif b/image/test/gtest/bug-1655846.avif
new file mode 100644
index 0000000000..31c7e42454
--- /dev/null
+++ b/image/test/gtest/bug-1655846.avif
Binary files differ
diff --git a/image/test/gtest/corrupt-with-bad-bmp-height.ico b/image/test/gtest/corrupt-with-bad-bmp-height.ico
new file mode 100644
index 0000000000..ee4a90fcd7
--- /dev/null
+++ b/image/test/gtest/corrupt-with-bad-bmp-height.ico
Binary files differ
diff --git a/image/test/gtest/corrupt-with-bad-bmp-width.ico b/image/test/gtest/corrupt-with-bad-bmp-width.ico
new file mode 100644
index 0000000000..aa4051cd07
--- /dev/null
+++ b/image/test/gtest/corrupt-with-bad-bmp-width.ico
Binary files differ
diff --git a/image/test/gtest/corrupt-with-bad-ico-bpp.ico b/image/test/gtest/corrupt-with-bad-ico-bpp.ico
new file mode 100644
index 0000000000..5db4922e34
--- /dev/null
+++ b/image/test/gtest/corrupt-with-bad-ico-bpp.ico
Binary files differ
diff --git a/image/test/gtest/corrupt.jpg b/image/test/gtest/corrupt.jpg
new file mode 100644
index 0000000000..555a416d7d
--- /dev/null
+++ b/image/test/gtest/corrupt.jpg
Binary files differ
diff --git a/image/test/gtest/downscaled.avif b/image/test/gtest/downscaled.avif
new file mode 100644
index 0000000000..15aa14d240
--- /dev/null
+++ b/image/test/gtest/downscaled.avif
Binary files differ
diff --git a/image/test/gtest/downscaled.bmp b/image/test/gtest/downscaled.bmp
new file mode 100644
index 0000000000..9e6a29e62b
--- /dev/null
+++ b/image/test/gtest/downscaled.bmp
Binary files differ
diff --git a/image/test/gtest/downscaled.gif b/image/test/gtest/downscaled.gif
new file mode 100644
index 0000000000..ff9a20bcdb
--- /dev/null
+++ b/image/test/gtest/downscaled.gif
Binary files differ
diff --git a/image/test/gtest/downscaled.ico b/image/test/gtest/downscaled.ico
new file mode 100644
index 0000000000..ee112af0a9
--- /dev/null
+++ b/image/test/gtest/downscaled.ico
Binary files differ
diff --git a/image/test/gtest/downscaled.icon b/image/test/gtest/downscaled.icon
new file mode 100644
index 0000000000..0ec9139866
--- /dev/null
+++ b/image/test/gtest/downscaled.icon
Binary files differ
diff --git a/image/test/gtest/downscaled.jpg b/image/test/gtest/downscaled.jpg
new file mode 100644
index 0000000000..5a4b3cd036
--- /dev/null
+++ b/image/test/gtest/downscaled.jpg
Binary files differ
diff --git a/image/test/gtest/downscaled.jxl b/image/test/gtest/downscaled.jxl
new file mode 100644
index 0000000000..90e9f65ab2
--- /dev/null
+++ b/image/test/gtest/downscaled.jxl
Binary files differ
diff --git a/image/test/gtest/downscaled.png b/image/test/gtest/downscaled.png
new file mode 100644
index 0000000000..b71b4652d5
--- /dev/null
+++ b/image/test/gtest/downscaled.png
Binary files differ
diff --git a/image/test/gtest/downscaled.webp b/image/test/gtest/downscaled.webp
new file mode 100644
index 0000000000..c2db6d6446
--- /dev/null
+++ b/image/test/gtest/downscaled.webp
Binary files differ
diff --git a/image/test/gtest/exif_resolution.jpg b/image/test/gtest/exif_resolution.jpg
new file mode 100644
index 0000000000..757ce2d877
--- /dev/null
+++ b/image/test/gtest/exif_resolution.jpg
Binary files differ
diff --git a/image/test/gtest/first-frame-green.avif b/image/test/gtest/first-frame-green.avif
new file mode 100644
index 0000000000..9f2417664f
--- /dev/null
+++ b/image/test/gtest/first-frame-green.avif
Binary files differ
diff --git a/image/test/gtest/first-frame-green.gif b/image/test/gtest/first-frame-green.gif
new file mode 100644
index 0000000000..cd3c7d3db8
--- /dev/null
+++ b/image/test/gtest/first-frame-green.gif
Binary files differ
diff --git a/image/test/gtest/first-frame-green.png b/image/test/gtest/first-frame-green.png
new file mode 100644
index 0000000000..115f035d89
--- /dev/null
+++ b/image/test/gtest/first-frame-green.png
Binary files differ
diff --git a/image/test/gtest/first-frame-green.webp b/image/test/gtest/first-frame-green.webp
new file mode 100644
index 0000000000..44db5c71c3
--- /dev/null
+++ b/image/test/gtest/first-frame-green.webp
Binary files differ
diff --git a/image/test/gtest/first-frame-padding.gif b/image/test/gtest/first-frame-padding.gif
new file mode 100644
index 0000000000..e6d7c49322
--- /dev/null
+++ b/image/test/gtest/first-frame-padding.gif
Binary files differ
diff --git a/image/test/gtest/gray-235-10bit-full-range-bt2020.avif b/image/test/gtest/gray-235-10bit-full-range-bt2020.avif
new file mode 100644
index 0000000000..33603adc6e
--- /dev/null
+++ b/image/test/gtest/gray-235-10bit-full-range-bt2020.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-10bit-full-range-bt601.avif b/image/test/gtest/gray-235-10bit-full-range-bt601.avif
new file mode 100644
index 0000000000..d8bbd550b1
--- /dev/null
+++ b/image/test/gtest/gray-235-10bit-full-range-bt601.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-10bit-full-range-bt709.avif b/image/test/gtest/gray-235-10bit-full-range-bt709.avif
new file mode 100644
index 0000000000..a2bae8ce21
--- /dev/null
+++ b/image/test/gtest/gray-235-10bit-full-range-bt709.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-10bit-full-range-grayscale.avif b/image/test/gtest/gray-235-10bit-full-range-grayscale.avif
new file mode 100644
index 0000000000..bb64ee7bfe
--- /dev/null
+++ b/image/test/gtest/gray-235-10bit-full-range-grayscale.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-10bit-limited-range-bt2020.avif b/image/test/gtest/gray-235-10bit-limited-range-bt2020.avif
new file mode 100644
index 0000000000..13ab0d258e
--- /dev/null
+++ b/image/test/gtest/gray-235-10bit-limited-range-bt2020.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-10bit-limited-range-bt601.avif b/image/test/gtest/gray-235-10bit-limited-range-bt601.avif
new file mode 100644
index 0000000000..e0bc194c3f
--- /dev/null
+++ b/image/test/gtest/gray-235-10bit-limited-range-bt601.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-10bit-limited-range-bt709.avif b/image/test/gtest/gray-235-10bit-limited-range-bt709.avif
new file mode 100644
index 0000000000..bff8d79aa8
--- /dev/null
+++ b/image/test/gtest/gray-235-10bit-limited-range-bt709.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-10bit-limited-range-grayscale.avif b/image/test/gtest/gray-235-10bit-limited-range-grayscale.avif
new file mode 100644
index 0000000000..297be0f2bc
--- /dev/null
+++ b/image/test/gtest/gray-235-10bit-limited-range-grayscale.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-12bit-full-range-bt2020.avif b/image/test/gtest/gray-235-12bit-full-range-bt2020.avif
new file mode 100644
index 0000000000..5f42432364
--- /dev/null
+++ b/image/test/gtest/gray-235-12bit-full-range-bt2020.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-12bit-full-range-bt601.avif b/image/test/gtest/gray-235-12bit-full-range-bt601.avif
new file mode 100644
index 0000000000..e681f44356
--- /dev/null
+++ b/image/test/gtest/gray-235-12bit-full-range-bt601.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-12bit-full-range-bt709.avif b/image/test/gtest/gray-235-12bit-full-range-bt709.avif
new file mode 100644
index 0000000000..608e41d54b
--- /dev/null
+++ b/image/test/gtest/gray-235-12bit-full-range-bt709.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-12bit-full-range-grayscale.avif b/image/test/gtest/gray-235-12bit-full-range-grayscale.avif
new file mode 100644
index 0000000000..9ced94abfd
--- /dev/null
+++ b/image/test/gtest/gray-235-12bit-full-range-grayscale.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-12bit-limited-range-bt2020.avif b/image/test/gtest/gray-235-12bit-limited-range-bt2020.avif
new file mode 100644
index 0000000000..1673a67d21
--- /dev/null
+++ b/image/test/gtest/gray-235-12bit-limited-range-bt2020.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-12bit-limited-range-bt601.avif b/image/test/gtest/gray-235-12bit-limited-range-bt601.avif
new file mode 100644
index 0000000000..fbd1938c90
--- /dev/null
+++ b/image/test/gtest/gray-235-12bit-limited-range-bt601.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-12bit-limited-range-bt709.avif b/image/test/gtest/gray-235-12bit-limited-range-bt709.avif
new file mode 100644
index 0000000000..38e4bbff7c
--- /dev/null
+++ b/image/test/gtest/gray-235-12bit-limited-range-bt709.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-12bit-limited-range-grayscale.avif b/image/test/gtest/gray-235-12bit-limited-range-grayscale.avif
new file mode 100644
index 0000000000..415b09afe5
--- /dev/null
+++ b/image/test/gtest/gray-235-12bit-limited-range-grayscale.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-8bit-full-range-bt2020.avif b/image/test/gtest/gray-235-8bit-full-range-bt2020.avif
new file mode 100644
index 0000000000..ad5aea1fe2
--- /dev/null
+++ b/image/test/gtest/gray-235-8bit-full-range-bt2020.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-8bit-full-range-bt601.avif b/image/test/gtest/gray-235-8bit-full-range-bt601.avif
new file mode 100644
index 0000000000..a4692b2110
--- /dev/null
+++ b/image/test/gtest/gray-235-8bit-full-range-bt601.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-8bit-full-range-bt709.avif b/image/test/gtest/gray-235-8bit-full-range-bt709.avif
new file mode 100644
index 0000000000..80c3406dd2
--- /dev/null
+++ b/image/test/gtest/gray-235-8bit-full-range-bt709.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-8bit-full-range-grayscale.avif b/image/test/gtest/gray-235-8bit-full-range-grayscale.avif
new file mode 100644
index 0000000000..39abf34204
--- /dev/null
+++ b/image/test/gtest/gray-235-8bit-full-range-grayscale.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-8bit-limited-range-bt2020.avif b/image/test/gtest/gray-235-8bit-limited-range-bt2020.avif
new file mode 100644
index 0000000000..30782d98d6
--- /dev/null
+++ b/image/test/gtest/gray-235-8bit-limited-range-bt2020.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-8bit-limited-range-bt601.avif b/image/test/gtest/gray-235-8bit-limited-range-bt601.avif
new file mode 100644
index 0000000000..ccb10e3e57
--- /dev/null
+++ b/image/test/gtest/gray-235-8bit-limited-range-bt601.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-8bit-limited-range-bt709.avif b/image/test/gtest/gray-235-8bit-limited-range-bt709.avif
new file mode 100644
index 0000000000..350fed532d
--- /dev/null
+++ b/image/test/gtest/gray-235-8bit-limited-range-bt709.avif
Binary files differ
diff --git a/image/test/gtest/gray-235-8bit-limited-range-grayscale.avif b/image/test/gtest/gray-235-8bit-limited-range-grayscale.avif
new file mode 100644
index 0000000000..f4dc38f160
--- /dev/null
+++ b/image/test/gtest/gray-235-8bit-limited-range-grayscale.avif
Binary files differ
diff --git a/image/test/gtest/green-1x1-truncated.gif b/image/test/gtest/green-1x1-truncated.gif
new file mode 100644
index 0000000000..0829f9694d
--- /dev/null
+++ b/image/test/gtest/green-1x1-truncated.gif
Binary files differ
diff --git a/image/test/gtest/green-large-bmp.ico b/image/test/gtest/green-large-bmp.ico
new file mode 100644
index 0000000000..3962cea29d
--- /dev/null
+++ b/image/test/gtest/green-large-bmp.ico
Binary files differ
diff --git a/image/test/gtest/green-large-png.ico b/image/test/gtest/green-large-png.ico
new file mode 100644
index 0000000000..27b9f43cdd
--- /dev/null
+++ b/image/test/gtest/green-large-png.ico
Binary files differ
diff --git a/image/test/gtest/green-multiple-sizes.ico b/image/test/gtest/green-multiple-sizes.ico
new file mode 100644
index 0000000000..b9463d0c89
--- /dev/null
+++ b/image/test/gtest/green-multiple-sizes.ico
Binary files differ
diff --git a/image/test/gtest/green.avif b/image/test/gtest/green.avif
new file mode 100644
index 0000000000..3178de7f5e
--- /dev/null
+++ b/image/test/gtest/green.avif
Binary files differ
diff --git a/image/test/gtest/green.bmp b/image/test/gtest/green.bmp
new file mode 100644
index 0000000000..f79dd672ad
--- /dev/null
+++ b/image/test/gtest/green.bmp
Binary files differ
diff --git a/image/test/gtest/green.gif b/image/test/gtest/green.gif
new file mode 100644
index 0000000000..ef215dfc94
--- /dev/null
+++ b/image/test/gtest/green.gif
Binary files differ
diff --git a/image/test/gtest/green.icc_srgb.webp b/image/test/gtest/green.icc_srgb.webp
new file mode 100644
index 0000000000..2a869b447b
--- /dev/null
+++ b/image/test/gtest/green.icc_srgb.webp
Binary files differ
diff --git a/image/test/gtest/green.ico b/image/test/gtest/green.ico
new file mode 100644
index 0000000000..c5dfa8b538
--- /dev/null
+++ b/image/test/gtest/green.ico
Binary files differ
diff --git a/image/test/gtest/green.icon b/image/test/gtest/green.icon
new file mode 100644
index 0000000000..1de4eeb783
--- /dev/null
+++ b/image/test/gtest/green.icon
Binary files differ
diff --git a/image/test/gtest/green.jpg b/image/test/gtest/green.jpg
new file mode 100644
index 0000000000..48c454d27c
--- /dev/null
+++ b/image/test/gtest/green.jpg
Binary files differ
diff --git a/image/test/gtest/green.jxl b/image/test/gtest/green.jxl
new file mode 100644
index 0000000000..357f8f392e
--- /dev/null
+++ b/image/test/gtest/green.jxl
Binary files differ
diff --git a/image/test/gtest/green.png b/image/test/gtest/green.png
new file mode 100644
index 0000000000..7df25f33bd
--- /dev/null
+++ b/image/test/gtest/green.png
Binary files differ
diff --git a/image/test/gtest/green.webp b/image/test/gtest/green.webp
new file mode 100644
index 0000000000..04b7f003b4
--- /dev/null
+++ b/image/test/gtest/green.webp
Binary files differ
diff --git a/image/test/gtest/hdlr-nonzero-reserved-bug-1727033.avif b/image/test/gtest/hdlr-nonzero-reserved-bug-1727033.avif
new file mode 100644
index 0000000000..e84ba63e2d
--- /dev/null
+++ b/image/test/gtest/hdlr-nonzero-reserved-bug-1727033.avif
Binary files differ
diff --git a/image/test/gtest/invalid-truncated-metadata.bmp b/image/test/gtest/invalid-truncated-metadata.bmp
new file mode 100644
index 0000000000..228c5c9992
--- /dev/null
+++ b/image/test/gtest/invalid-truncated-metadata.bmp
Binary files differ
diff --git a/image/test/gtest/large.avif b/image/test/gtest/large.avif
new file mode 100644
index 0000000000..fbdf084148
--- /dev/null
+++ b/image/test/gtest/large.avif
Binary files differ
diff --git a/image/test/gtest/large.jxl b/image/test/gtest/large.jxl
new file mode 100644
index 0000000000..a244e66b7d
--- /dev/null
+++ b/image/test/gtest/large.jxl
Binary files differ
diff --git a/image/test/gtest/large.webp b/image/test/gtest/large.webp
new file mode 100644
index 0000000000..9bf0b64fa8
--- /dev/null
+++ b/image/test/gtest/large.webp
Binary files differ
diff --git a/image/test/gtest/moz.build b/image/test/gtest/moz.build
new file mode 100644
index 0000000000..d563ec202c
--- /dev/null
+++ b/image/test/gtest/moz.build
@@ -0,0 +1,156 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+Library("imagetest")
+
+UNIFIED_SOURCES = [
+ "Common.cpp",
+ "TestADAM7InterpolatingFilter.cpp",
+ "TestAnimationFrameBuffer.cpp",
+ "TestBlendAnimationFilter.cpp",
+ "TestCopyOnWrite.cpp",
+ "TestDeinterlacingFilter.cpp",
+ "TestFrameAnimator.cpp",
+ "TestLoader.cpp",
+ "TestRemoveFrameRectFilter.cpp",
+ "TestStreamingLexer.cpp",
+ "TestSurfaceSink.cpp",
+ "TestSwizzleFilter.cpp",
+]
+
+# skip the test on windows10-aarch64, aarch64 due to 1544961
+if not (CONFIG["OS_TARGET"] == "WINNT" and CONFIG["CPU_ARCH"] == "aarch64"):
+ UNIFIED_SOURCES += [
+ "TestDecoders.cpp",
+ "TestDecodersPerf.cpp",
+ "TestDecodeToSurface.cpp",
+ "TestMetadata.cpp",
+ "TestSourceBuffer.cpp",
+ "TestSurfaceCache.cpp",
+ ]
+
+UNIFIED_SOURCES += [
+ "TestDownscalingFilter.cpp",
+ "TestSurfacePipeIntegration.cpp",
+]
+
+TEST_HARNESS_FILES.gtest += [
+ "animated-with-extra-image-sub-blocks.gif",
+ "blend.avif",
+ "blend.gif",
+ "blend.png",
+ "blend.webp",
+ "bug-1655846.avif",
+ "corrupt-with-bad-bmp-height.ico",
+ "corrupt-with-bad-bmp-width.ico",
+ "corrupt-with-bad-ico-bpp.ico",
+ "corrupt.jpg",
+ "downscaled.avif",
+ "downscaled.bmp",
+ "downscaled.gif",
+ "downscaled.ico",
+ "downscaled.icon",
+ "downscaled.jpg",
+ "downscaled.jxl",
+ "downscaled.png",
+ "downscaled.webp",
+ "exif_resolution.jpg",
+ "first-frame-green.avif",
+ "first-frame-green.gif",
+ "first-frame-green.png",
+ "first-frame-green.webp",
+ "first-frame-padding.gif",
+ "gray-235-10bit-full-range-bt2020.avif",
+ "gray-235-10bit-full-range-bt601.avif",
+ "gray-235-10bit-full-range-bt709.avif",
+ "gray-235-10bit-full-range-grayscale.avif",
+ "gray-235-10bit-limited-range-bt2020.avif",
+ "gray-235-10bit-limited-range-bt601.avif",
+ "gray-235-10bit-limited-range-bt709.avif",
+ "gray-235-10bit-limited-range-grayscale.avif",
+ "gray-235-12bit-full-range-bt2020.avif",
+ "gray-235-12bit-full-range-bt601.avif",
+ "gray-235-12bit-full-range-bt709.avif",
+ "gray-235-12bit-full-range-grayscale.avif",
+ "gray-235-12bit-limited-range-bt2020.avif",
+ "gray-235-12bit-limited-range-bt601.avif",
+ "gray-235-12bit-limited-range-bt709.avif",
+ "gray-235-12bit-limited-range-grayscale.avif",
+ "gray-235-8bit-full-range-bt2020.avif",
+ "gray-235-8bit-full-range-bt601.avif",
+ "gray-235-8bit-full-range-bt709.avif",
+ "gray-235-8bit-full-range-grayscale.avif",
+ "gray-235-8bit-limited-range-bt2020.avif",
+ "gray-235-8bit-limited-range-bt601.avif",
+ "gray-235-8bit-limited-range-bt709.avif",
+ "gray-235-8bit-limited-range-grayscale.avif",
+ "green-1x1-truncated.gif",
+ "green-large-bmp.ico",
+ "green-large-png.ico",
+ "green-multiple-sizes.ico",
+ "green.avif",
+ "green.bmp",
+ "green.gif",
+ "green.icc_srgb.webp",
+ "green.ico",
+ "green.icon",
+ "green.jpg",
+ "green.jxl",
+ "green.png",
+ "green.webp",
+ "hdlr-nonzero-reserved-bug-1727033.avif",
+ "invalid-truncated-metadata.bmp",
+ "large.avif",
+ "large.jxl",
+ "large.webp",
+ "multilayer.avif",
+ "no-frame-delay.gif",
+ "perf_cmyk.jpg",
+ "perf_gray.jpg",
+ "perf_gray.png",
+ "perf_gray_alpha.png",
+ "perf_srgb.gif",
+ "perf_srgb.png",
+ "perf_srgb_alpha.png",
+ "perf_srgb_alpha_lossless.webp",
+ "perf_srgb_alpha_lossy.webp",
+ "perf_srgb_lossless.webp",
+ "perf_srgb_lossy.webp",
+ "perf_ycbcr.jpg",
+ "rle4.bmp",
+ "rle8.bmp",
+ "stackcheck.avif",
+ "transparent-green-50pct-10bit-yuv420.avif",
+ "transparent-green-50pct-10bit-yuv422.avif",
+ "transparent-green-50pct-10bit-yuv444.avif",
+ "transparent-green-50pct-12bit-yuv420.avif",
+ "transparent-green-50pct-12bit-yuv422.avif",
+ "transparent-green-50pct-12bit-yuv444.avif",
+ "transparent-green-50pct-8bit-yuv420.avif",
+ "transparent-green-50pct-8bit-yuv422.avif",
+ "transparent-green-50pct-8bit-yuv444.avif",
+ "transparent-ico-with-and-mask.ico",
+ "transparent-if-within-ico.bmp",
+ "transparent-no-alpha-header.webp",
+ "transparent.avif",
+ "transparent.gif",
+ "transparent.jxl",
+ "transparent.png",
+ "transparent.webp",
+ "valid-avif-colr-nclx-and-prof.avif",
+]
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+LOCAL_INCLUDES += [
+ "/dom/base",
+ "/gfx/2d",
+ "/image",
+]
+
+LOCAL_INCLUDES += CONFIG["SKIA_INCLUDES"]
+
+FINAL_LIBRARY = "xul-gtest"
diff --git a/image/test/gtest/multilayer.avif b/image/test/gtest/multilayer.avif
new file mode 100644
index 0000000000..91857fde54
--- /dev/null
+++ b/image/test/gtest/multilayer.avif
Binary files differ
diff --git a/image/test/gtest/no-frame-delay.gif b/image/test/gtest/no-frame-delay.gif
new file mode 100644
index 0000000000..1c50b67431
--- /dev/null
+++ b/image/test/gtest/no-frame-delay.gif
Binary files differ
diff --git a/image/test/gtest/perf_cmyk.jpg b/image/test/gtest/perf_cmyk.jpg
new file mode 100644
index 0000000000..e9d329f21e
--- /dev/null
+++ b/image/test/gtest/perf_cmyk.jpg
Binary files differ
diff --git a/image/test/gtest/perf_gray.jpg b/image/test/gtest/perf_gray.jpg
new file mode 100644
index 0000000000..ed75b91550
--- /dev/null
+++ b/image/test/gtest/perf_gray.jpg
Binary files differ
diff --git a/image/test/gtest/perf_gray.png b/image/test/gtest/perf_gray.png
new file mode 100644
index 0000000000..df16c72fb6
--- /dev/null
+++ b/image/test/gtest/perf_gray.png
Binary files differ
diff --git a/image/test/gtest/perf_gray_alpha.png b/image/test/gtest/perf_gray_alpha.png
new file mode 100644
index 0000000000..fc38ec549b
--- /dev/null
+++ b/image/test/gtest/perf_gray_alpha.png
Binary files differ
diff --git a/image/test/gtest/perf_srgb.gif b/image/test/gtest/perf_srgb.gif
new file mode 100644
index 0000000000..4dadf118b5
--- /dev/null
+++ b/image/test/gtest/perf_srgb.gif
Binary files differ
diff --git a/image/test/gtest/perf_srgb.png b/image/test/gtest/perf_srgb.png
new file mode 100644
index 0000000000..21f28081c2
--- /dev/null
+++ b/image/test/gtest/perf_srgb.png
Binary files differ
diff --git a/image/test/gtest/perf_srgb_alpha.png b/image/test/gtest/perf_srgb_alpha.png
new file mode 100644
index 0000000000..1fa7fed59b
--- /dev/null
+++ b/image/test/gtest/perf_srgb_alpha.png
Binary files differ
diff --git a/image/test/gtest/perf_srgb_alpha_lossless.webp b/image/test/gtest/perf_srgb_alpha_lossless.webp
new file mode 100644
index 0000000000..cce4c24ff4
--- /dev/null
+++ b/image/test/gtest/perf_srgb_alpha_lossless.webp
Binary files differ
diff --git a/image/test/gtest/perf_srgb_alpha_lossy.webp b/image/test/gtest/perf_srgb_alpha_lossy.webp
new file mode 100644
index 0000000000..1bc08edc7d
--- /dev/null
+++ b/image/test/gtest/perf_srgb_alpha_lossy.webp
Binary files differ
diff --git a/image/test/gtest/perf_srgb_lossless.webp b/image/test/gtest/perf_srgb_lossless.webp
new file mode 100644
index 0000000000..ae85a41237
--- /dev/null
+++ b/image/test/gtest/perf_srgb_lossless.webp
Binary files differ
diff --git a/image/test/gtest/perf_srgb_lossy.webp b/image/test/gtest/perf_srgb_lossy.webp
new file mode 100644
index 0000000000..3caad7ceca
--- /dev/null
+++ b/image/test/gtest/perf_srgb_lossy.webp
Binary files differ
diff --git a/image/test/gtest/perf_ycbcr.jpg b/image/test/gtest/perf_ycbcr.jpg
new file mode 100644
index 0000000000..d2ad4e2b20
--- /dev/null
+++ b/image/test/gtest/perf_ycbcr.jpg
Binary files differ
diff --git a/image/test/gtest/rle4.bmp b/image/test/gtest/rle4.bmp
new file mode 100644
index 0000000000..78a0927870
--- /dev/null
+++ b/image/test/gtest/rle4.bmp
Binary files differ
diff --git a/image/test/gtest/rle8.bmp b/image/test/gtest/rle8.bmp
new file mode 100644
index 0000000000..bd793b6b66
--- /dev/null
+++ b/image/test/gtest/rle8.bmp
Binary files differ
diff --git a/image/test/gtest/stackcheck.avif b/image/test/gtest/stackcheck.avif
new file mode 100644
index 0000000000..fbc9c34dee
--- /dev/null
+++ b/image/test/gtest/stackcheck.avif
Binary files differ
diff --git a/image/test/gtest/transparent-green-50pct-10bit-yuv420.avif b/image/test/gtest/transparent-green-50pct-10bit-yuv420.avif
new file mode 100644
index 0000000000..453840f40c
--- /dev/null
+++ b/image/test/gtest/transparent-green-50pct-10bit-yuv420.avif
Binary files differ
diff --git a/image/test/gtest/transparent-green-50pct-10bit-yuv422.avif b/image/test/gtest/transparent-green-50pct-10bit-yuv422.avif
new file mode 100644
index 0000000000..91e0e75417
--- /dev/null
+++ b/image/test/gtest/transparent-green-50pct-10bit-yuv422.avif
Binary files differ
diff --git a/image/test/gtest/transparent-green-50pct-10bit-yuv444.avif b/image/test/gtest/transparent-green-50pct-10bit-yuv444.avif
new file mode 100644
index 0000000000..65f265ed96
--- /dev/null
+++ b/image/test/gtest/transparent-green-50pct-10bit-yuv444.avif
Binary files differ
diff --git a/image/test/gtest/transparent-green-50pct-12bit-yuv420.avif b/image/test/gtest/transparent-green-50pct-12bit-yuv420.avif
new file mode 100644
index 0000000000..9945c50a46
--- /dev/null
+++ b/image/test/gtest/transparent-green-50pct-12bit-yuv420.avif
Binary files differ
diff --git a/image/test/gtest/transparent-green-50pct-12bit-yuv422.avif b/image/test/gtest/transparent-green-50pct-12bit-yuv422.avif
new file mode 100644
index 0000000000..f428c51f08
--- /dev/null
+++ b/image/test/gtest/transparent-green-50pct-12bit-yuv422.avif
Binary files differ
diff --git a/image/test/gtest/transparent-green-50pct-12bit-yuv444.avif b/image/test/gtest/transparent-green-50pct-12bit-yuv444.avif
new file mode 100644
index 0000000000..811acc3a10
--- /dev/null
+++ b/image/test/gtest/transparent-green-50pct-12bit-yuv444.avif
Binary files differ
diff --git a/image/test/gtest/transparent-green-50pct-8bit-yuv420.avif b/image/test/gtest/transparent-green-50pct-8bit-yuv420.avif
new file mode 100644
index 0000000000..25c1940bde
--- /dev/null
+++ b/image/test/gtest/transparent-green-50pct-8bit-yuv420.avif
Binary files differ
diff --git a/image/test/gtest/transparent-green-50pct-8bit-yuv422.avif b/image/test/gtest/transparent-green-50pct-8bit-yuv422.avif
new file mode 100644
index 0000000000..2f58be6441
--- /dev/null
+++ b/image/test/gtest/transparent-green-50pct-8bit-yuv422.avif
Binary files differ
diff --git a/image/test/gtest/transparent-green-50pct-8bit-yuv444.avif b/image/test/gtest/transparent-green-50pct-8bit-yuv444.avif
new file mode 100644
index 0000000000..ab83b3ba77
--- /dev/null
+++ b/image/test/gtest/transparent-green-50pct-8bit-yuv444.avif
Binary files differ
diff --git a/image/test/gtest/transparent-ico-with-and-mask.ico b/image/test/gtest/transparent-ico-with-and-mask.ico
new file mode 100644
index 0000000000..ab0dc4bce1
--- /dev/null
+++ b/image/test/gtest/transparent-ico-with-and-mask.ico
Binary files differ
diff --git a/image/test/gtest/transparent-if-within-ico.bmp b/image/test/gtest/transparent-if-within-ico.bmp
new file mode 100644
index 0000000000..4dc04c181b
--- /dev/null
+++ b/image/test/gtest/transparent-if-within-ico.bmp
Binary files differ
diff --git a/image/test/gtest/transparent-no-alpha-header.webp b/image/test/gtest/transparent-no-alpha-header.webp
new file mode 100644
index 0000000000..8ddd73ac7a
--- /dev/null
+++ b/image/test/gtest/transparent-no-alpha-header.webp
Binary files differ
diff --git a/image/test/gtest/transparent.avif b/image/test/gtest/transparent.avif
new file mode 100644
index 0000000000..00ef35bf74
--- /dev/null
+++ b/image/test/gtest/transparent.avif
Binary files differ
diff --git a/image/test/gtest/transparent.gif b/image/test/gtest/transparent.gif
new file mode 100644
index 0000000000..48f5c7caf1
--- /dev/null
+++ b/image/test/gtest/transparent.gif
Binary files differ
diff --git a/image/test/gtest/transparent.jxl b/image/test/gtest/transparent.jxl
new file mode 100644
index 0000000000..c479164516
--- /dev/null
+++ b/image/test/gtest/transparent.jxl
Binary files differ
diff --git a/image/test/gtest/transparent.png b/image/test/gtest/transparent.png
new file mode 100644
index 0000000000..fc8002053a
--- /dev/null
+++ b/image/test/gtest/transparent.png
Binary files differ
diff --git a/image/test/gtest/transparent.webp b/image/test/gtest/transparent.webp
new file mode 100644
index 0000000000..87b9520521
--- /dev/null
+++ b/image/test/gtest/transparent.webp
Binary files differ
diff --git a/image/test/gtest/valid-avif-colr-nclx-and-prof.avif b/image/test/gtest/valid-avif-colr-nclx-and-prof.avif
new file mode 100644
index 0000000000..683baa7f54
--- /dev/null
+++ b/image/test/gtest/valid-avif-colr-nclx-and-prof.avif
Binary files differ
diff --git a/image/test/mochitest/12M-pixels-1.png b/image/test/mochitest/12M-pixels-1.png
new file mode 100644
index 0000000000..f802dd5396
--- /dev/null
+++ b/image/test/mochitest/12M-pixels-1.png
Binary files differ
diff --git a/image/test/mochitest/12M-pixels-2.png b/image/test/mochitest/12M-pixels-2.png
new file mode 100644
index 0000000000..a6d430442e
--- /dev/null
+++ b/image/test/mochitest/12M-pixels-2.png
Binary files differ
diff --git a/image/test/mochitest/6M-pixels.png b/image/test/mochitest/6M-pixels.png
new file mode 100644
index 0000000000..c813d8b569
--- /dev/null
+++ b/image/test/mochitest/6M-pixels.png
Binary files differ
diff --git a/image/test/mochitest/INT32_MIN.bmp b/image/test/mochitest/INT32_MIN.bmp
new file mode 100644
index 0000000000..d9a0016107
--- /dev/null
+++ b/image/test/mochitest/INT32_MIN.bmp
Binary files differ
diff --git a/image/test/mochitest/animated-avif.avif b/image/test/mochitest/animated-avif.avif
new file mode 100644
index 0000000000..f3cafef1e3
--- /dev/null
+++ b/image/test/mochitest/animated-avif.avif
Binary files differ
diff --git a/image/test/mochitest/animated-gif-finalframe.gif b/image/test/mochitest/animated-gif-finalframe.gif
new file mode 100644
index 0000000000..4e80d31a72
--- /dev/null
+++ b/image/test/mochitest/animated-gif-finalframe.gif
Binary files differ
diff --git a/image/test/mochitest/animated-gif.gif b/image/test/mochitest/animated-gif.gif
new file mode 100644
index 0000000000..001cbfb87a
--- /dev/null
+++ b/image/test/mochitest/animated-gif.gif
Binary files differ
diff --git a/image/test/mochitest/animated-gif2.gif b/image/test/mochitest/animated-gif2.gif
new file mode 100644
index 0000000000..c66cc4b734
--- /dev/null
+++ b/image/test/mochitest/animated-gif2.gif
Binary files differ
diff --git a/image/test/mochitest/animated-gif_trailing-garbage.gif b/image/test/mochitest/animated-gif_trailing-garbage.gif
new file mode 100644
index 0000000000..02f4de2e31
--- /dev/null
+++ b/image/test/mochitest/animated-gif_trailing-garbage.gif
Binary files differ
diff --git a/image/test/mochitest/animated1.gif b/image/test/mochitest/animated1.gif
new file mode 100644
index 0000000000..2f9d8a512b
--- /dev/null
+++ b/image/test/mochitest/animated1.gif
Binary files differ
diff --git a/image/test/mochitest/animated1.svg b/image/test/mochitest/animated1.svg
new file mode 100644
index 0000000000..87118c4ea0
--- /dev/null
+++ b/image/test/mochitest/animated1.svg
@@ -0,0 +1,12 @@
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ style="animation: colorAnim 1s steps(2) infinite alternate"
+ width="40" height="40">
+ <style>
+ @keyframes colorAnim {
+ from { background-color: green }
+ to { background-color: blue }
+ }
+ </style>
+</svg>
+
diff --git a/image/test/mochitest/animated2.gif b/image/test/mochitest/animated2.gif
new file mode 100644
index 0000000000..2f9d8a512b
--- /dev/null
+++ b/image/test/mochitest/animated2.gif
Binary files differ
diff --git a/image/test/mochitest/animatedMask.gif b/image/test/mochitest/animatedMask.gif
new file mode 100644
index 0000000000..72a1c51ddc
--- /dev/null
+++ b/image/test/mochitest/animatedMask.gif
Binary files differ
diff --git a/image/test/mochitest/animation.svg b/image/test/mochitest/animation.svg
new file mode 100644
index 0000000000..2141d86791
--- /dev/null
+++ b/image/test/mochitest/animation.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <image id="anim" xlink:href="animated-gif.gif" width="40" height="40"/>
+</svg>
+
diff --git a/image/test/mochitest/animationPolling.js b/image/test/mochitest/animationPolling.js
new file mode 100644
index 0000000000..f20377cf9d
--- /dev/null
+++ b/image/test/mochitest/animationPolling.js
@@ -0,0 +1,469 @@
+// This file expects imgutils.js to be loaded as well.
+/* import-globals-from imgutils.js */
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+var currentTest;
+var gIsRefImageLoaded = false;
+const gShouldOutputDebugInfo = false;
+
+function pollForSuccess() {
+ if (!currentTest.isTestFinished) {
+ if (
+ !currentTest.reusingReferenceImage ||
+ (currentTest.reusingReferenceImage && gIsRefImageLoaded)
+ ) {
+ currentTest.checkImage();
+ }
+
+ setTimeout(pollForSuccess, currentTest.pollFreq);
+ }
+}
+
+function reuseImageCallback() {
+ gIsRefImageLoaded = true;
+}
+
+function failTest() {
+ if (currentTest.isTestFinished || currentTest.closeFunc) {
+ return;
+ }
+
+ ok(
+ false,
+ "timing out after " +
+ currentTest.timeout +
+ "ms. " +
+ "Animated image still doesn't look correct, after poll #" +
+ currentTest.pollCounter
+ );
+ currentTest.wereFailures = true;
+
+ if (currentTest.currentSnapshotDataURI) {
+ currentTest.outputDebugInfo(
+ "Snapshot #" + currentTest.pollCounter,
+ "snapNum" + currentTest.pollCounter,
+ currentTest.currentSnapshotDataURI
+ );
+ }
+
+ currentTest.enableDisplay(
+ document.getElementById(currentTest.debugElementId)
+ );
+
+ currentTest.cleanUpAndFinish();
+}
+
+/**
+ * Create a new AnimationTest object.
+ *
+ * @param pollFreq The amount of time (in ms) to wait between consecutive
+ * snapshots if the reference image and the test image don't match.
+ * @param timeout The total amount of time (in ms) to wait before declaring the
+ * test as failed.
+ * @param referenceElementId The id attribute of the reference image element, or
+ * the source of the image to change to, once the reference snapshot has
+ * been successfully taken. This latter option could be used if you don't
+ * want the image to become invisible at any time during the test.
+ * @param imageElementId The id attribute of the test image element.
+ * @param debugElementId The id attribute of the div where links should be
+ * appended if the test fails.
+ * @param cleanId The id attribute of the div or element to use as the 'clean'
+ * test. This element is only enabled when we are testing to verify that
+ * the reference image has been loaded. It can be undefined.
+ * @param srcAttr The location of the source of the image, for preloading. This
+ * is usually not required, but it useful for preloading reference
+ * images.
+ * @param xulTest A boolean value indicating whether or not this is a XUL test
+ * (uses hidden=true/false rather than display: none to hide/show
+ * elements).
+ * @param closeFunc A function that should be called when this test is finished.
+ * If null, then cleanUpAndFinish() will be called. This can be used to
+ * chain tests together, so they are all finished exactly once.
+ * @returns {AnimationTest}
+ */
+function AnimationTest(
+ pollFreq,
+ timeout,
+ referenceElementId,
+ imageElementId,
+ debugElementId,
+ cleanId,
+ srcAttr,
+ xulTest,
+ closeFunc
+) {
+ // We want to test the cold loading behavior, so clear cache in case an
+ // earlier test got our image in there already.
+ clearAllImageCaches();
+
+ this.wereFailures = false;
+ this.pollFreq = pollFreq;
+ this.timeout = timeout;
+ this.imageElementId = imageElementId;
+ this.referenceElementId = referenceElementId;
+
+ if (!document.getElementById(referenceElementId)) {
+ // In this case, we're assuming the user passed in a string that
+ // indicates the source of the image they want to change to,
+ // after the reference image has been taken.
+ this.reusingImageAsReference = true;
+ }
+
+ this.srcAttr = srcAttr;
+ this.debugElementId = debugElementId;
+ this.referenceSnapshot = ""; // value will be set in takeReferenceSnapshot()
+ this.pollCounter = 0;
+ this.isTestFinished = false;
+ this.numRefsTaken = 0;
+ this.blankWaitTime = 0;
+
+ this.cleanId = cleanId ? cleanId : "";
+ this.xulTest = xulTest ? xulTest : "";
+ this.closeFunc = closeFunc ? closeFunc : "";
+}
+
+AnimationTest.prototype.preloadImage = function () {
+ if (this.srcAttr) {
+ this.myImage = new Image();
+ this.myImage.onload = function () {
+ currentTest.continueTest();
+ };
+ this.myImage.src = this.srcAttr;
+ } else {
+ this.continueTest();
+ }
+};
+
+AnimationTest.prototype.outputDebugInfo = function (message, id, dataUri) {
+ if (!gShouldOutputDebugInfo) {
+ return;
+ }
+ var debugElement = document.getElementById(this.debugElementId);
+ var newDataUriElement = document.createElement("a");
+ newDataUriElement.setAttribute("id", id);
+ newDataUriElement.setAttribute("href", dataUri);
+ newDataUriElement.appendChild(document.createTextNode(message));
+ debugElement.appendChild(newDataUriElement);
+ var brElement = document.createElement("br");
+ debugElement.appendChild(brElement);
+ todo(false, "Debug (" + id + "): " + message + " " + dataUri);
+};
+
+AnimationTest.prototype.isFinished = function () {
+ return this.isTestFinished;
+};
+
+AnimationTest.prototype.takeCleanSnapshot = function () {
+ var cleanElement;
+ if (this.cleanId) {
+ cleanElement = document.getElementById(this.cleanId);
+ }
+
+ // Enable clean page comparison element
+ if (cleanElement) {
+ this.enableDisplay(cleanElement);
+ }
+
+ // Take a snapshot of the initial (clean) page
+ this.cleanSnapshot = snapshotWindow(window, false);
+
+ // Disable the clean page comparison element
+ if (cleanElement) {
+ this.disableDisplay(cleanElement);
+ }
+
+ var dataString1 = "Clean Snapshot";
+ this.outputDebugInfo(
+ dataString1,
+ "cleanSnap",
+ this.cleanSnapshot.toDataURL()
+ );
+};
+
+AnimationTest.prototype.takeBlankSnapshot = function () {
+ // Take a snapshot of the initial (essentially blank) page
+ this.blankSnapshot = snapshotWindow(window, false);
+
+ var dataString1 = "Initial Blank Snapshot";
+ this.outputDebugInfo(
+ dataString1,
+ "blank1Snap",
+ this.blankSnapshot.toDataURL()
+ );
+};
+
+/**
+ * Begin the AnimationTest. This will utilize the information provided in the
+ * constructor to invoke a mochitest on animated images. It will automatically
+ * fail if allowed to run past the timeout. This will attempt to preload an
+ * image, if applicable, and then asynchronously call continueTest(), or if not
+ * applicable, synchronously trigger a call to continueTest().
+ */
+AnimationTest.prototype.beginTest = function () {
+ SimpleTest.waitForExplicitFinish();
+ SimpleTest.requestFlakyTimeout("untriaged");
+
+ currentTest = this;
+ this.preloadImage();
+};
+
+/**
+ * This is the second part of the test. It is triggered (eventually) from
+ * beginTest() either synchronously or asynchronously, as an image load
+ * callback.
+ */
+AnimationTest.prototype.continueTest = async function () {
+ // In case something goes wrong, fail earlier than mochitest timeout,
+ // and with more information.
+ setTimeout(failTest, this.timeout);
+
+ if (!this.reusingImageAsReference) {
+ this.disableDisplay(document.getElementById(this.imageElementId));
+ }
+
+ let tookReference = new Promise(resolve => {
+ this.takeReferenceSnapshot(resolve);
+ });
+
+ tookReference.then(() => {
+ this.setupPolledImage();
+ SimpleTest.executeSoon(pollForSuccess);
+ });
+};
+
+AnimationTest.prototype.setupPolledImage = function () {
+ // Make sure the image is visible
+ if (!this.reusingImageAsReference) {
+ this.enableDisplay(document.getElementById(this.imageElementId));
+ var currentSnapshot = snapshotWindow(window, false);
+ var result = compareSnapshots(
+ currentSnapshot,
+ this.referenceSnapshot,
+ true
+ );
+
+ this.currentSnapshotDataURI = currentSnapshot.toDataURL();
+
+ if (result[0]) {
+ // SUCCESS!
+ ok(true, "Animated image looks correct, at poll #" + this.pollCounter);
+
+ this.outputDebugInfo(
+ "Animated image",
+ "animImage",
+ this.currentSnapshotDataURI
+ );
+
+ this.outputDebugInfo(
+ "Reference image",
+ "refImage",
+ this.referenceSnapshot.toDataURL()
+ );
+
+ this.cleanUpAndFinish();
+ }
+ } else if (!gIsRefImageLoaded) {
+ this.myImage = new Image();
+ this.myImage.onload = reuseImageCallback;
+ document
+ .getElementById(this.imageElementId)
+ .setAttribute("src", this.referenceElementId);
+ }
+};
+
+AnimationTest.prototype.checkImage = function () {
+ if (this.isTestFinished) {
+ return;
+ }
+
+ this.pollCounter++;
+
+ // We need this for some tests, because we need to force the
+ // test image to be visible.
+ if (!this.reusingImageAsReference) {
+ this.enableDisplay(document.getElementById(this.imageElementId));
+ }
+
+ var currentSnapshot = snapshotWindow(window, false);
+ var result = compareSnapshots(currentSnapshot, this.referenceSnapshot, true);
+
+ this.currentSnapshotDataURI = currentSnapshot.toDataURL();
+
+ if (result[0]) {
+ // SUCCESS!
+ ok(true, "Animated image looks correct, at poll #" + this.pollCounter);
+
+ this.outputDebugInfo("Animated image", "animImage", result[1]);
+
+ this.outputDebugInfo("Reference image", "refImage", result[2]);
+
+ this.cleanUpAndFinish();
+ }
+};
+
+AnimationTest.prototype.takeReferenceSnapshot = function (resolve) {
+ this.numRefsTaken++;
+
+ // Test to make sure the reference image doesn't match a clean snapshot
+ if (!this.cleanSnapshot) {
+ this.takeCleanSnapshot();
+ }
+
+ // Used later to verify that the reference div disappeared
+ if (!this.blankSnapshot) {
+ this.takeBlankSnapshot();
+ }
+
+ if (this.reusingImageAsReference) {
+ // Show reference elem (which is actually our image), & take a snapshot
+ var referenceElem = document.getElementById(this.imageElementId);
+ this.enableDisplay(referenceElem);
+
+ this.referenceSnapshot = snapshotWindow(window, false);
+
+ let snapResult = compareSnapshots(
+ this.cleanSnapshot,
+ this.referenceSnapshot,
+ false
+ );
+ if (!snapResult[0]) {
+ if (this.blankWaitTime > 2000) {
+ // if it took longer than two seconds to load the image, we probably
+ // have a problem.
+ this.wereFailures = true;
+ ok(
+ snapResult[0],
+ "Reference snapshot shouldn't match clean (non-image) snapshot"
+ );
+ } else {
+ this.blankWaitTime += currentTest.pollFreq;
+ // let's wait a bit and see if it clears up
+ setTimeout(
+ () => this.takeReferenceSnapshot(resolve),
+ currentTest.pollFreq
+ );
+ return;
+ }
+ }
+
+ ok(
+ snapResult[0],
+ "Reference snapshot shouldn't match clean (non-image) snapshot"
+ );
+
+ let dataString = "Reference Snapshot #" + this.numRefsTaken;
+ this.outputDebugInfo(
+ dataString,
+ "refSnapId",
+ this.referenceSnapshot.toDataURL()
+ );
+ } else {
+ // Make sure the animation section is hidden
+ this.disableDisplay(document.getElementById(this.imageElementId));
+
+ // Show reference div, & take a snapshot
+ var referenceDiv = document.getElementById(this.referenceElementId);
+ this.enableDisplay(referenceDiv);
+
+ this.referenceSnapshot = snapshotWindow(window, false);
+ let snapResult = compareSnapshots(
+ this.cleanSnapshot,
+ this.referenceSnapshot,
+ false
+ );
+ if (!snapResult[0]) {
+ if (this.blankWaitTime > 2000) {
+ // if it took longer than two seconds to load the image, we probably
+ // have a problem.
+ this.wereFailures = true;
+ ok(
+ snapResult[0],
+ "Reference snapshot shouldn't match clean (non-image) snapshot"
+ );
+ } else {
+ this.blankWaitTime += 20;
+ // let's wait a bit and see if it clears up
+ setTimeout(() => this.takeReferenceSnapshot(resolve), 20);
+ return;
+ }
+ }
+
+ ok(
+ snapResult[0],
+ "Reference snapshot shouldn't match clean (non-image) snapshot"
+ );
+
+ let dataString = "Reference Snapshot #" + this.numRefsTaken;
+ this.outputDebugInfo(
+ dataString,
+ "refSnapId",
+ this.referenceSnapshot.toDataURL()
+ );
+
+ // Re-hide reference div, and take another snapshot to be sure it's gone
+ this.disableDisplay(referenceDiv);
+ this.testBlankCameBack();
+ }
+ resolve();
+};
+
+AnimationTest.prototype.enableDisplay = function (element) {
+ if (!element) {
+ return;
+ }
+
+ if (!this.xulTest) {
+ element.style.display = "";
+ } else {
+ element.setAttribute("hidden", "false");
+ }
+};
+
+AnimationTest.prototype.disableDisplay = function (element) {
+ if (!element) {
+ return;
+ }
+
+ if (!this.xulTest) {
+ element.style.display = "none";
+ } else {
+ element.setAttribute("hidden", "true");
+ }
+};
+
+AnimationTest.prototype.testBlankCameBack = function () {
+ var blankSnapshot2 = snapshotWindow(window, false);
+ var result = compareSnapshots(this.blankSnapshot, blankSnapshot2, true);
+ ok(
+ result[0],
+ "Reference image should disappear when it becomes display:none"
+ );
+
+ if (!result[0]) {
+ this.wereFailures = true;
+ var dataString = "Second Blank Snapshot";
+ this.outputDebugInfo(dataString, "blank2SnapId", result[2]);
+ }
+};
+
+AnimationTest.prototype.cleanUpAndFinish = function () {
+ // On the off chance that failTest and checkImage are triggered
+ // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish.
+ if (this.isTestFinished) {
+ return;
+ }
+
+ this.isTestFinished = true;
+
+ // Call our closing function, if one exists
+ if (this.closeFunc) {
+ this.closeFunc();
+ return;
+ }
+
+ if (this.wereFailures) {
+ document.getElementById(this.debugElementId).style.display = "block";
+ }
+
+ SimpleTest.finish();
+ document.getElementById(this.debugElementId).style.display = "";
+};
diff --git a/image/test/mochitest/bad.jpg b/image/test/mochitest/bad.jpg
new file mode 100644
index 0000000000..555a416d7d
--- /dev/null
+++ b/image/test/mochitest/bad.jpg
Binary files differ
diff --git a/image/test/mochitest/big.png b/image/test/mochitest/big.png
new file mode 100644
index 0000000000..94e7eb6db2
--- /dev/null
+++ b/image/test/mochitest/big.png
Binary files differ
diff --git a/image/test/mochitest/blue.gif b/image/test/mochitest/blue.gif
new file mode 100644
index 0000000000..339f3702fb
--- /dev/null
+++ b/image/test/mochitest/blue.gif
Binary files differ
diff --git a/image/test/mochitest/blue.png b/image/test/mochitest/blue.png
new file mode 100644
index 0000000000..8df58f3a5f
--- /dev/null
+++ b/image/test/mochitest/blue.png
Binary files differ
diff --git a/image/test/mochitest/bug1132427.gif b/image/test/mochitest/bug1132427.gif
new file mode 100644
index 0000000000..39f49689a0
--- /dev/null
+++ b/image/test/mochitest/bug1132427.gif
Binary files differ
diff --git a/image/test/mochitest/bug1132427.html b/image/test/mochitest/bug1132427.html
new file mode 100644
index 0000000000..c765ce14ca
--- /dev/null
+++ b/image/test/mochitest/bug1132427.html
@@ -0,0 +1,6 @@
+<html>
+<body onload="opener.doTest();">
+ <img id="left" style="width: 201px; height: 201px;" src="bug1132427.gif">
+ <img id="right" src="bug1132427.gif">
+</body>
+</html>
diff --git a/image/test/mochitest/bug1180105-waiter.sjs b/image/test/mochitest/bug1180105-waiter.sjs
new file mode 100644
index 0000000000..4e20cb9976
--- /dev/null
+++ b/image/test/mochitest/bug1180105-waiter.sjs
@@ -0,0 +1,29 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var timer = Cc["@mozilla.org/timer;1"];
+var waitTimer = timer.createInstance(Ci.nsITimer);
+
+function handleRequest(request, response) {
+ response.setHeader("Content-Type", "text/html", false);
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setStatusLine(request.httpVersion, 200, "OK");
+ response.processAsync();
+ waitForFinish(response);
+}
+
+function waitForFinish(response) {
+ if (getSharedState("all-parts-done") === "1") {
+ response.write("done");
+ response.finish();
+ } else {
+ waitTimer.initWithCallback(
+ function () {
+ waitForFinish(response);
+ },
+ 10,
+ Ci.nsITimer.TYPE_ONE_SHOT
+ );
+ }
+}
diff --git a/image/test/mochitest/bug1180105.sjs b/image/test/mochitest/bug1180105.sjs
new file mode 100644
index 0000000000..35c7025508
--- /dev/null
+++ b/image/test/mochitest/bug1180105.sjs
@@ -0,0 +1,68 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var counter = 100;
+var timer = Cc["@mozilla.org/timer;1"];
+var partTimer = timer.createInstance(Ci.nsITimer);
+
+function getFileAsInputStream(aFilename) {
+ var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
+
+ file.append("tests");
+ file.append("image");
+ file.append("test");
+ file.append("mochitest");
+ file.append(aFilename);
+
+ var fileStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ fileStream.init(file, 1, 0, false);
+ return fileStream;
+}
+
+function handleRequest(request, response) {
+ response.setHeader(
+ "Content-Type",
+ "multipart/x-mixed-replace;boundary=BOUNDARYOMG",
+ false
+ );
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setStatusLine(request.httpVersion, 200, "OK");
+ // We're sending parts off in a delayed fashion, to let the tests occur.
+ response.processAsync();
+ response.write("--BOUNDARYOMG\r\n");
+ sendParts(response);
+}
+
+function sendParts(response) {
+ if (counter-- == 0) {
+ sendClose(response);
+ setSharedState("all-parts-done", "1");
+ return;
+ }
+ sendNextPart(response);
+ partTimer.initWithCallback(
+ function () {
+ sendParts(response);
+ },
+ 1,
+ Ci.nsITimer.TYPE_ONE_SHOT
+ );
+}
+
+function sendClose(response) {
+ response.write("--BOUNDARYOMG--\r\n");
+ response.finish();
+}
+
+function sendNextPart(response) {
+ var nextPartHead = "Content-Type: image/jpeg\r\n\r\n";
+ var inputStream = getFileAsInputStream("damon.jpg");
+ response.bodyOutputStream.write(nextPartHead, nextPartHead.length);
+ response.bodyOutputStream.writeFrom(inputStream, inputStream.available());
+ inputStream.close();
+ // Toss in the boundary, so the browser can know this part is complete
+ response.write("--BOUNDARYOMG\r\n");
+}
diff --git a/image/test/mochitest/bug1217571-iframe.html b/image/test/mochitest/bug1217571-iframe.html
new file mode 100644
index 0000000000..ab243d5cf5
--- /dev/null
+++ b/image/test/mochitest/bug1217571-iframe.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1217571
+-->
+<head>
+ <title>iframe for Bug 1217571</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <img src="bug1217571.jpg">
+</div>
+</body>
+</html>
diff --git a/image/test/mochitest/bug1217571.jpg b/image/test/mochitest/bug1217571.jpg
new file mode 100644
index 0000000000..917b336607
--- /dev/null
+++ b/image/test/mochitest/bug1217571.jpg
Binary files differ
diff --git a/image/test/mochitest/bug1319025-ref.png b/image/test/mochitest/bug1319025-ref.png
new file mode 100644
index 0000000000..482d027a02
--- /dev/null
+++ b/image/test/mochitest/bug1319025-ref.png
Binary files differ
diff --git a/image/test/mochitest/bug1319025.png b/image/test/mochitest/bug1319025.png
new file mode 100644
index 0000000000..8023e77879
--- /dev/null
+++ b/image/test/mochitest/bug1319025.png
Binary files differ
diff --git a/image/test/mochitest/bug399925.gif b/image/test/mochitest/bug399925.gif
new file mode 100644
index 0000000000..fc1c8f3af0
--- /dev/null
+++ b/image/test/mochitest/bug399925.gif
Binary files differ
diff --git a/image/test/mochitest/bug415761.ico b/image/test/mochitest/bug415761.ico
new file mode 100644
index 0000000000..d3f65abc23
--- /dev/null
+++ b/image/test/mochitest/bug415761.ico
Binary files differ
diff --git a/image/test/mochitest/bug468160.sjs b/image/test/mochitest/bug468160.sjs
new file mode 100644
index 0000000000..6495482922
--- /dev/null
+++ b/image/test/mochitest/bug468160.sjs
@@ -0,0 +1,5 @@
+function handleRequest(request, response) {
+ response.setStatusLine("1.1", 302, "Found");
+ response.setHeader("Location", "red.png", false);
+ response.setHeader("Cache-Control", "no-cache", false);
+}
diff --git a/image/test/mochitest/bug478398_ONLY.png b/image/test/mochitest/bug478398_ONLY.png
new file mode 100644
index 0000000000..e094ae2cf4
--- /dev/null
+++ b/image/test/mochitest/bug478398_ONLY.png
Binary files differ
diff --git a/image/test/mochitest/bug490949-iframe.html b/image/test/mochitest/bug490949-iframe.html
new file mode 100644
index 0000000000..68f74b587e
--- /dev/null
+++ b/image/test/mochitest/bug490949-iframe.html
@@ -0,0 +1,7 @@
+<html>
+<head>
+<title>Bug 490949 iframe</title>
+<body>
+<img src="bug490949.sjs" width="100" height="100" id="image" />
+</body>
+</html>
diff --git a/image/test/mochitest/bug490949.sjs b/image/test/mochitest/bug490949.sjs
new file mode 100644
index 0000000000..3b77dd9232
--- /dev/null
+++ b/image/test/mochitest/bug490949.sjs
@@ -0,0 +1,32 @@
+function handleRequest(request, response) {
+ var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
+
+ file.append("tests");
+ file.append("image");
+ file.append("test");
+ file.append("mochitest");
+
+ var redirectstate = "/image/test/mochitest/bug490949.sjs";
+ if (getState(redirectstate) == "") {
+ file.append("blue.png");
+ setState(redirectstate, "red");
+ } else {
+ file.append("red.png");
+ setState(redirectstate, "");
+ }
+ response.setHeader("Cache-Control", "no-cache", false);
+
+ var fileStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ fileStream.init(file, 1, 0, false);
+ var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
+ Ci.nsIBinaryInputStream
+ );
+ binaryStream.setInputStream(fileStream);
+
+ response.bodyOutputStream.writeFrom(binaryStream, binaryStream.available());
+
+ binaryStream.close();
+ fileStream.close();
+}
diff --git a/image/test/mochitest/bug496292-1.sjs b/image/test/mochitest/bug496292-1.sjs
new file mode 100644
index 0000000000..2e842223d5
--- /dev/null
+++ b/image/test/mochitest/bug496292-1.sjs
@@ -0,0 +1,31 @@
+function handleRequest(request, response) {
+ var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
+
+ file.append("tests");
+ file.append("image");
+ file.append("test");
+ file.append("mochitest");
+
+ if (request.getHeader("Accept") == "image/avif,image/webp,*/*") {
+ file.append("blue.png");
+ } else {
+ file.append("red.png");
+ }
+ response.setStatusLine(request.httpVersion, 200, "OK");
+ response.setHeader("Content-Type", "image/png", false);
+ response.setHeader("Cache-Control", "no-cache", false);
+
+ var fileStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ fileStream.init(file, 1, 0, false);
+ var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
+ Ci.nsIBinaryInputStream
+ );
+ binaryStream.setInputStream(fileStream);
+
+ response.bodyOutputStream.writeFrom(binaryStream, binaryStream.available());
+
+ binaryStream.close();
+ fileStream.close();
+}
diff --git a/image/test/mochitest/bug496292-2.sjs b/image/test/mochitest/bug496292-2.sjs
new file mode 100644
index 0000000000..af174e99c4
--- /dev/null
+++ b/image/test/mochitest/bug496292-2.sjs
@@ -0,0 +1,31 @@
+function handleRequest(request, response) {
+ var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
+
+ file.append("tests");
+ file.append("image");
+ file.append("test");
+ file.append("mochitest");
+
+ if (request.getHeader("Accept") == "image/png") {
+ file.append("blue.png");
+ } else {
+ file.append("red.png");
+ }
+ response.setStatusLine(request.httpVersion, 200, "OK");
+ response.setHeader("Content-Type", "image/png", false);
+ response.setHeader("Cache-Control", "no-cache", false);
+
+ var fileStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ fileStream.init(file, 1, 0, false);
+ var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
+ Ci.nsIBinaryInputStream
+ );
+ binaryStream.setInputStream(fileStream);
+
+ response.bodyOutputStream.writeFrom(binaryStream, binaryStream.available());
+
+ binaryStream.close();
+ fileStream.close();
+}
diff --git a/image/test/mochitest/bug496292-iframe-1.html b/image/test/mochitest/bug496292-iframe-1.html
new file mode 100644
index 0000000000..00f0fbcfce
--- /dev/null
+++ b/image/test/mochitest/bug496292-iframe-1.html
@@ -0,0 +1,7 @@
+<html>
+<head>
+<title>Bug 496292 iframe 1</title>
+<body>
+<img src="bug496292-1.sjs" width="100" height="100" id="image" />
+</body>
+</html>
diff --git a/image/test/mochitest/bug496292-iframe-2.html b/image/test/mochitest/bug496292-iframe-2.html
new file mode 100644
index 0000000000..67c1ecea16
--- /dev/null
+++ b/image/test/mochitest/bug496292-iframe-2.html
@@ -0,0 +1,7 @@
+<html>
+<head>
+<title>Bug 496292 iframe 2</title>
+<body>
+<img src="bug496292-2.sjs" width="100" height="100" id="image" />
+</body>
+</html>
diff --git a/image/test/mochitest/bug496292-iframe-ref.html b/image/test/mochitest/bug496292-iframe-ref.html
new file mode 100644
index 0000000000..2e804502e6
--- /dev/null
+++ b/image/test/mochitest/bug496292-iframe-ref.html
@@ -0,0 +1,7 @@
+<html>
+<head>
+<title>Bug 496292 reference iframe</title>
+<body>
+<img src="blue.png" width="100" height="100" id="image" />
+</body>
+</html>
diff --git a/image/test/mochitest/bug497665-iframe.html b/image/test/mochitest/bug497665-iframe.html
new file mode 100644
index 0000000000..a2b098e31b
--- /dev/null
+++ b/image/test/mochitest/bug497665-iframe.html
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>Bug 497665 iframe</title>
+<body>
+<img src="bug497665.sjs" width="100" height="100" id="image1" />
+<img src="bug497665.sjs" width="100" height="100" id="image2" />
+</body>
+</html>
diff --git a/image/test/mochitest/bug497665.sjs b/image/test/mochitest/bug497665.sjs
new file mode 100644
index 0000000000..cc6361d7c5
--- /dev/null
+++ b/image/test/mochitest/bug497665.sjs
@@ -0,0 +1,33 @@
+function handleRequest(request, response) {
+ var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
+
+ file.append("tests");
+ file.append("image");
+ file.append("test");
+ file.append("mochitest");
+
+ var redirectstate = "/image/test/mochitest/bug497665.sjs";
+ if (getState(redirectstate) == "") {
+ file.append("blue.png");
+ setState(redirectstate, "red");
+ } else {
+ file.append("red.png");
+ setState(redirectstate, "");
+ }
+
+ response.setHeader("Cache-Control", "max-age=3600", false);
+
+ var fileStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ fileStream.init(file, 1, 0, false);
+ var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
+ Ci.nsIBinaryInputStream
+ );
+ binaryStream.setInputStream(fileStream);
+
+ response.bodyOutputStream.writeFrom(binaryStream, binaryStream.available());
+
+ binaryStream.close();
+ fileStream.close();
+}
diff --git a/image/test/mochitest/bug552605.sjs b/image/test/mochitest/bug552605.sjs
new file mode 100644
index 0000000000..350ab729d5
--- /dev/null
+++ b/image/test/mochitest/bug552605.sjs
@@ -0,0 +1,12 @@
+function handleRequest(request, response) {
+ var redirectstate = "/image/test/mochitest/bug89419.sjs";
+ response.setStatusLine("1.1", 302, "Found");
+ if (getState(redirectstate) == "") {
+ response.setHeader("Location", "red.png", false);
+ setState(redirectstate, "red");
+ } else {
+ response.setHeader("Location", "blue.png", false);
+ setState(redirectstate, "");
+ }
+ response.setHeader("Cache-Control", "no-cache", false);
+}
diff --git a/image/test/mochitest/bug657191.sjs b/image/test/mochitest/bug657191.sjs
new file mode 100644
index 0000000000..6a2c7924e1
--- /dev/null
+++ b/image/test/mochitest/bug657191.sjs
@@ -0,0 +1,26 @@
+function handleRequest(request, response) {
+ var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
+
+ file.append("tests");
+ file.append("image");
+ file.append("test");
+ file.append("mochitest");
+ file.append("lime100x100.svg");
+
+ response.setStatusLine("1.1", 500, "Internal Server Error");
+ response.setHeader("Content-Type", "image/svg+xml", false);
+
+ var fileStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ fileStream.init(file, 1, 0, false);
+ var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
+ Ci.nsIBinaryInputStream
+ );
+ binaryStream.setInputStream(fileStream);
+
+ response.bodyOutputStream.writeFrom(binaryStream, binaryStream.available());
+
+ binaryStream.close();
+ fileStream.close();
+}
diff --git a/image/test/mochitest/bug671906-iframe.html b/image/test/mochitest/bug671906-iframe.html
new file mode 100644
index 0000000000..87f8183a4d
--- /dev/null
+++ b/image/test/mochitest/bug671906-iframe.html
@@ -0,0 +1,7 @@
+<html>
+<head>
+<title>Bug 671906 iframe</title>
+<body>
+<img src="http://mochi.test:8888/tests/image/test/mochitest/bug671906.sjs" width="100" height="100" crossorigin="anonymous" />
+</body>
+</html>
diff --git a/image/test/mochitest/bug671906.sjs b/image/test/mochitest/bug671906.sjs
new file mode 100644
index 0000000000..8473e87f3a
--- /dev/null
+++ b/image/test/mochitest/bug671906.sjs
@@ -0,0 +1,34 @@
+function handleRequest(request, response) {
+ var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
+
+ file.append("tests");
+ file.append("image");
+ file.append("test");
+ file.append("mochitest");
+
+ var filestate = "/image/test/mochitest/bug671906.sjs";
+ if (getState(filestate) == "") {
+ file.append("blue.png");
+ setState(filestate, "red");
+ } else {
+ file.append("red.png");
+ setState(filestate, "");
+ }
+
+ // Set the expires date to some silly time in the future so we're sure to
+ // *want* to cache this image.
+ var date = new Date();
+ date.setFullYear(date.getFullYear() + 1);
+ response.setHeader("Expires", date.toUTCString(), false);
+
+ var fileStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ fileStream.init(file, 1, 0, false);
+
+ response.bodyOutputStream.writeFrom(fileStream, fileStream.available());
+
+ fileStream.close();
+
+ response.setHeader("Access-Control-Allow-Origin", "*", false);
+}
diff --git a/image/test/mochitest/bug733553-informant.sjs b/image/test/mochitest/bug733553-informant.sjs
new file mode 100644
index 0000000000..364830b636
--- /dev/null
+++ b/image/test/mochitest/bug733553-informant.sjs
@@ -0,0 +1,13 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+function handleRequest(request, response) {
+ response.setHeader("Content-Type", "text/plain", false);
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setStatusLine(request.httpVersion, 200, "OK");
+ // Tells bug733553.sjs that the consumer is ready for the next part
+ let partName = request.queryString;
+ setSharedState("next-part", partName);
+ response.write("OK!");
+}
diff --git a/image/test/mochitest/bug733553.sjs b/image/test/mochitest/bug733553.sjs
new file mode 100644
index 0000000000..869477b581
--- /dev/null
+++ b/image/test/mochitest/bug733553.sjs
@@ -0,0 +1,104 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var bodyPartIndex = -1;
+var bodyParts = [
+ ["red.png", "image/png"],
+ ["animated-gif2.gif", "image/gif"],
+ ["red.png", "image/png"],
+ ["lime100x100.svg", "image/svg+xml"],
+ ["lime100x100.svg", "image/svg+xml"],
+ ["animated-gif2.gif", "image/gif"],
+ ["red.png", "image/png"],
+ // Mime type intentionally wrong (test for bug 907575)
+ ["shaver.png", "image/gif"],
+ ["red.png", "image/png"],
+ ["damon.jpg", "image/jpeg"],
+ ["damon.jpg", "application/octet-stream"],
+ ["damon.jpg", "image/jpeg"],
+ ["rillybad.jpg", "application/x-unknown-content-type"],
+ ["damon.jpg", "image/jpeg"],
+ ["bad.jpg", "image/jpeg"],
+ ["red.png", "image/png"],
+ ["invalid.jpg", "image/jpeg"],
+ ["animated-gif2.gif", "image/gif"],
+];
+var timer = Cc["@mozilla.org/timer;1"];
+var partTimer = timer.createInstance(Ci.nsITimer);
+
+function getFileAsInputStream(aFilename) {
+ var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
+
+ file.append("tests");
+ file.append("image");
+ file.append("test");
+ file.append("mochitest");
+ file.append(aFilename);
+
+ var fileStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ fileStream.init(file, 1, 0, false);
+ return fileStream;
+}
+
+function handleRequest(request, response) {
+ if (!getSharedState("next-part")) {
+ setSharedState("next-part", "-1");
+ }
+ response.setHeader(
+ "Content-Type",
+ "multipart/x-mixed-replace;boundary=BOUNDARYOMG",
+ false
+ );
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setStatusLine(request.httpVersion, 200, "OK");
+ // We're sending parts off in a delayed fashion, to let the tests occur.
+ response.processAsync();
+ response.write("--BOUNDARYOMG\r\n");
+ sendParts(response);
+}
+
+function sendParts(response) {
+ let wait = false;
+ let nextPart = parseInt(getSharedState("next-part"), 10);
+ if (nextPart == bodyPartIndex) {
+ // Haven't been signaled yet, remain in holding pattern
+ wait = true;
+ } else {
+ bodyPartIndex = nextPart;
+ }
+ if (bodyParts.length > bodyPartIndex) {
+ let callback;
+ if (!wait) {
+ callback = getSendNextPart(response);
+ } else {
+ callback = function () {
+ sendParts(response);
+ };
+ }
+ partTimer.initWithCallback(callback, 1000, Ci.nsITimer.TYPE_ONE_SHOT);
+ } else {
+ sendClose(response);
+ }
+}
+
+function sendClose(response) {
+ response.write("--BOUNDARYOMG--\r\n");
+ response.finish();
+}
+
+function getSendNextPart(response) {
+ var part = bodyParts[bodyPartIndex];
+ var nextPartHead = "Content-Type: " + part[1] + "\r\n\r\n";
+ var inputStream = getFileAsInputStream(part[0]);
+ return function () {
+ response.bodyOutputStream.write(nextPartHead, nextPartHead.length);
+ response.bodyOutputStream.writeFrom(inputStream, inputStream.available());
+ inputStream.close();
+ // Toss in the boundary, so the browser can know this part is complete
+ response.write("--BOUNDARYOMG\r\n");
+ sendParts(response);
+ };
+}
diff --git a/image/test/mochitest/bug767779.sjs b/image/test/mochitest/bug767779.sjs
new file mode 100644
index 0000000000..b29b00cf1c
--- /dev/null
+++ b/image/test/mochitest/bug767779.sjs
@@ -0,0 +1,56 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var timer = Cc["@mozilla.org/timer;1"];
+var partTimer = timer.createInstance(Ci.nsITimer);
+
+function getFileAsInputStream(aFilename) {
+ var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
+
+ file.append("tests");
+ file.append("image");
+ file.append("test");
+ file.append("mochitest");
+ file.append(aFilename);
+
+ var fileStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ fileStream.init(file, 1, 0, false);
+ return fileStream;
+}
+
+function handleRequest(request, response) {
+ response.setHeader("Content-Type", "image/gif", false);
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setStatusLine(request.httpVersion, 200, "OK");
+ // We're sending data off in a delayed fashion
+ response.processAsync();
+ var inputStream = getFileAsInputStream("animated-gif_trailing-garbage.gif");
+ // Should be 4029 bytes available.
+ // Send the good data at once
+ response.bodyOutputStream.writeFrom(inputStream, 285);
+ sendParts(inputStream, response);
+}
+
+function sendParts(inputStream, response) {
+ // 3744 left, send in 8 chunks of 468 each
+ partTimer.initWithCallback(
+ getSendNextPart(inputStream, response),
+ 500,
+ Ci.nsITimer.TYPE_ONE_SHOT
+ );
+}
+
+function getSendNextPart(inputStream, response) {
+ return function () {
+ response.bodyOutputStream.writeFrom(inputStream, 468);
+ if (!inputStream.available()) {
+ inputStream.close();
+ response.finish();
+ } else {
+ sendParts(inputStream, response);
+ }
+ };
+}
diff --git a/image/test/mochitest/bug89419-iframe.html b/image/test/mochitest/bug89419-iframe.html
new file mode 100644
index 0000000000..1915315633
--- /dev/null
+++ b/image/test/mochitest/bug89419-iframe.html
@@ -0,0 +1,7 @@
+<html>
+<head>
+<title>Bug 89419 iframe</title>
+<body>
+<img src="bug89419.sjs" width="100" height="100" />
+</body>
+</html>
diff --git a/image/test/mochitest/bug89419.sjs b/image/test/mochitest/bug89419.sjs
new file mode 100644
index 0000000000..350ab729d5
--- /dev/null
+++ b/image/test/mochitest/bug89419.sjs
@@ -0,0 +1,12 @@
+function handleRequest(request, response) {
+ var redirectstate = "/image/test/mochitest/bug89419.sjs";
+ response.setStatusLine("1.1", 302, "Found");
+ if (getState(redirectstate) == "") {
+ response.setHeader("Location", "red.png", false);
+ setState(redirectstate, "red");
+ } else {
+ response.setHeader("Location", "blue.png", false);
+ setState(redirectstate, "");
+ }
+ response.setHeader("Cache-Control", "no-cache", false);
+}
diff --git a/image/test/mochitest/bug900200-ref.png b/image/test/mochitest/bug900200-ref.png
new file mode 100644
index 0000000000..6360131325
--- /dev/null
+++ b/image/test/mochitest/bug900200-ref.png
Binary files differ
diff --git a/image/test/mochitest/bug900200.png b/image/test/mochitest/bug900200.png
new file mode 100644
index 0000000000..d7d87adce0
--- /dev/null
+++ b/image/test/mochitest/bug900200.png
Binary files differ
diff --git a/image/test/mochitest/child.html b/image/test/mochitest/child.html
new file mode 100644
index 0000000000..19f262ec3a
--- /dev/null
+++ b/image/test/mochitest/child.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<script src="imgutils.js"></script>
+<img id="img" src="animated1.gif">
+<script>
+ let observer = new ImageDecoderObserverStub();
+ observer.decodeComplete = () => {
+ parent.postMessage("decodeComplete", "*");
+ };
+ observer.loadComplete = () => {
+ parent.postMessage("loadComplete", "*");
+ };
+ observer = SpecialPowers.wrapCallbackObject(observer);
+ const gObserver = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
+ .getService(SpecialPowers.Ci.imgITools)
+ .createScriptedObserver(observer);
+ const img = document.getElementById("img");
+ SpecialPowers.wrap(img).addObserver(gObserver);
+ window.addEventListener("unload", () => {
+ SpecialPowers.wrap(img).removeObserver(gObserver);
+ });
+</script>
diff --git a/image/test/mochitest/chrome.ini b/image/test/mochitest/chrome.ini
new file mode 100644
index 0000000000..b84d0af897
--- /dev/null
+++ b/image/test/mochitest/chrome.ini
@@ -0,0 +1,7 @@
+[DEFAULT]
+skip-if = os == 'android'
+
+[test_bug415761.html]
+skip-if = os != "win" || os_version == "6.2"
+support-files =
+ bug415761.ico
diff --git a/image/test/mochitest/clear.avif b/image/test/mochitest/clear.avif
new file mode 100644
index 0000000000..b68e5729b4
--- /dev/null
+++ b/image/test/mochitest/clear.avif
Binary files differ
diff --git a/image/test/mochitest/clear.gif b/image/test/mochitest/clear.gif
new file mode 100644
index 0000000000..7ae79ba86e
--- /dev/null
+++ b/image/test/mochitest/clear.gif
Binary files differ
diff --git a/image/test/mochitest/clear.png b/image/test/mochitest/clear.png
new file mode 100644
index 0000000000..b09aecaaa0
--- /dev/null
+++ b/image/test/mochitest/clear.png
Binary files differ
diff --git a/image/test/mochitest/clear.webp b/image/test/mochitest/clear.webp
new file mode 100644
index 0000000000..6db376d6e1
--- /dev/null
+++ b/image/test/mochitest/clear.webp
Binary files differ
diff --git a/image/test/mochitest/clear2-results.gif b/image/test/mochitest/clear2-results.gif
new file mode 100644
index 0000000000..965b650253
--- /dev/null
+++ b/image/test/mochitest/clear2-results.gif
Binary files differ
diff --git a/image/test/mochitest/clear2.gif b/image/test/mochitest/clear2.gif
new file mode 100644
index 0000000000..00ad873c65
--- /dev/null
+++ b/image/test/mochitest/clear2.gif
Binary files differ
diff --git a/image/test/mochitest/clear2.webp b/image/test/mochitest/clear2.webp
new file mode 100644
index 0000000000..e4a3e2efab
--- /dev/null
+++ b/image/test/mochitest/clear2.webp
Binary files differ
diff --git a/image/test/mochitest/damon.jpg b/image/test/mochitest/damon.jpg
new file mode 100644
index 0000000000..917b336607
--- /dev/null
+++ b/image/test/mochitest/damon.jpg
Binary files differ
diff --git a/image/test/mochitest/error-early.png b/image/test/mochitest/error-early.png
new file mode 100644
index 0000000000..5df7507e2d
--- /dev/null
+++ b/image/test/mochitest/error-early.png
@@ -0,0 +1 @@
+ERROR
diff --git a/image/test/mochitest/filter-final.svg b/image/test/mochitest/filter-final.svg
new file mode 100644
index 0000000000..b2b3dca008
--- /dev/null
+++ b/image/test/mochitest/filter-final.svg
@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+<filter id="filter1" x="0%" y="0%" width="100%" height="100%">
+ <feImage xlink:href="animated-gif-finalframe.gif"/>
+</filter>
+<g>
+ <rect x="0" y="0" width="100%" height="100%" filter="url(#filter1)"/>
+</g>
+</svg>
diff --git a/image/test/mochitest/filter.svg b/image/test/mochitest/filter.svg
new file mode 100644
index 0000000000..e185f15b69
--- /dev/null
+++ b/image/test/mochitest/filter.svg
@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+<filter id="filter1" x="0%" y="0%" width="100%" height="100%">
+ <feImage xlink:href="animated-gif.gif"/>
+</filter>
+<g>
+ <rect x="0" y="0" width="100%" height="100%" filter="url(#filter1)"/>
+</g>
+</svg>
diff --git a/image/test/mochitest/finite-apng.png b/image/test/mochitest/finite-apng.png
new file mode 100644
index 0000000000..778613d851
--- /dev/null
+++ b/image/test/mochitest/finite-apng.png
Binary files differ
diff --git a/image/test/mochitest/first-frame-padding.gif b/image/test/mochitest/first-frame-padding.gif
new file mode 100644
index 0000000000..e6d7c49322
--- /dev/null
+++ b/image/test/mochitest/first-frame-padding.gif
Binary files differ
diff --git a/image/test/mochitest/green-background.html b/image/test/mochitest/green-background.html
new file mode 100644
index 0000000000..731919f766
--- /dev/null
+++ b/image/test/mochitest/green-background.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>Background color wrapper for clear image tests</title>
+<style>
+body { margin: 0; }
+img {
+ background-color: rgb(0, 255, 0);
+}
+</style>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img id="image1" alt=" ">
+<script>
+// Loads an externally specified image and displays it
+// with a green background. Intended for use with tests
+// involving clear images.
+
+// Use as "green-background.html?image.png".
+
+// Get the image URL.
+var imgURL = document.location.search.substr(1);
+
+// Load it.
+var img = document.images[0];
+img.src = imgURL;
+</script>
+</body>
+</html>
diff --git a/image/test/mochitest/green.png b/image/test/mochitest/green.png
new file mode 100644
index 0000000000..7df25f33bd
--- /dev/null
+++ b/image/test/mochitest/green.png
Binary files differ
diff --git a/image/test/mochitest/grey.png b/image/test/mochitest/grey.png
new file mode 100644
index 0000000000..5c82cdeb10
--- /dev/null
+++ b/image/test/mochitest/grey.png
Binary files differ
diff --git a/image/test/mochitest/ico-bmp-opaque.ico b/image/test/mochitest/ico-bmp-opaque.ico
new file mode 100644
index 0000000000..3cf3320eae
--- /dev/null
+++ b/image/test/mochitest/ico-bmp-opaque.ico
Binary files differ
diff --git a/image/test/mochitest/ico-bmp-transparent.ico b/image/test/mochitest/ico-bmp-transparent.ico
new file mode 100644
index 0000000000..151b7cb361
--- /dev/null
+++ b/image/test/mochitest/ico-bmp-transparent.ico
Binary files differ
diff --git a/image/test/mochitest/iframe.html b/image/test/mochitest/iframe.html
new file mode 100644
index 0000000000..6d66557ef8
--- /dev/null
+++ b/image/test/mochitest/iframe.html
@@ -0,0 +1,5 @@
+<html>
+<body bgcolor="gray">
+ <img src="animated-gif.gif">
+</body>
+</html> \ No newline at end of file
diff --git a/image/test/mochitest/imgutils.js b/image/test/mochitest/imgutils.js
new file mode 100644
index 0000000000..b16ad1d065
--- /dev/null
+++ b/image/test/mochitest/imgutils.js
@@ -0,0 +1,137 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+// Helper file for shared image functionality
+//
+// Note that this is use by tests elsewhere in the source tree. When in doubt,
+// check mxr before removing or changing functionality.
+
+// Helper function to clear both the content and chrome image caches
+function clearAllImageCaches() {
+ var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"].getService(
+ SpecialPowers.Ci.imgITools
+ );
+ var imageCache = tools.getImgCacheForDocument(window.document);
+ imageCache.clearCache(true); // true=chrome
+ imageCache.clearCache(false); // false=content
+}
+
+// Helper function to clear the image cache of content images
+function clearImageCache() {
+ var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"].getService(
+ SpecialPowers.Ci.imgITools
+ );
+ var imageCache = tools.getImgCacheForDocument(window.document);
+ imageCache.clearCache(false); // true=chrome, false=content
+}
+
+// Helper function to determine if the frame is decoded for a given image id
+function isFrameDecoded(id) {
+ return !!(
+ getImageStatus(id) & SpecialPowers.Ci.imgIRequest.STATUS_FRAME_COMPLETE
+ );
+}
+
+// Helper function to determine if the image is loaded for a given image id
+function isImageLoaded(id) {
+ return !!(
+ getImageStatus(id) & SpecialPowers.Ci.imgIRequest.STATUS_LOAD_COMPLETE
+ );
+}
+
+// Helper function to get the status flags of an image
+function getImageStatus(id) {
+ // Get the image
+ var img = SpecialPowers.wrap(document.getElementById(id));
+
+ // Get the request
+ var request = img.getRequest(
+ SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST
+ );
+
+ // Return the status
+ return request.imageStatus;
+}
+
+// Forces a synchronous decode of an image by drawing it to a canvas. Only
+// really meaningful if the image is fully loaded first
+function forceDecode(id) {
+ // Get the image
+ var img = document.getElementById(id);
+
+ // Make a new canvas
+ var canvas = document.createElement("canvas");
+
+ // Draw the image to the canvas. This forces a synchronous decode
+ var ctx = canvas.getContext("2d");
+ ctx.drawImage(img, 0, 0);
+}
+
+// Functions to facilitate getting/setting various image-related prefs
+//
+// If you change a pref in a mochitest, Don't forget to reset it to its
+// original value!
+//
+// Null indicates no pref set
+
+const DISCARD_ENABLED_PREF = {
+ name: "discardable",
+ branch: "image.mem.",
+ type: "bool",
+};
+const DECODEONDRAW_ENABLED_PREF = {
+ name: "decodeondraw",
+ branch: "image.mem.",
+ type: "bool",
+};
+const DISCARD_TIMEOUT_PREF = {
+ name: "min_discard_timeout_ms",
+ branch: "image.mem.",
+ type: "int",
+};
+
+function setImagePref(pref, val) {
+ var prefService = SpecialPowers.Services.prefs;
+ var branch = prefService.getBranch(pref.branch);
+ if (val != null) {
+ switch (pref.type) {
+ case "bool":
+ branch.setBoolPref(pref.name, val);
+ break;
+ case "int":
+ branch.setIntPref(pref.name, val);
+ break;
+ default:
+ throw new Error("Unknown pref type");
+ }
+ } else if (branch.prefHasUserValue(pref.name)) {
+ branch.clearUserPref(pref.name);
+ }
+}
+
+function getImagePref(pref) {
+ var prefService = SpecialPowers.Services.prefs;
+ var branch = prefService.getBranch(pref.branch);
+ if (branch.prefHasUserValue(pref.name)) {
+ switch (pref.type) {
+ case "bool":
+ return branch.getBoolPref(pref.name);
+ case "int":
+ return branch.getIntPref(pref.name);
+ default:
+ throw new Error("Unknown pref type");
+ }
+ } else {
+ return null;
+ }
+}
+
+// JS implementation of imgIScriptedNotificationObserver with stubs for all of its methods.
+function ImageDecoderObserverStub() {
+ this.sizeAvailable = function sizeAvailable(aRequest) {};
+ this.frameComplete = function frameComplete(aRequest) {};
+ this.decodeComplete = function decodeComplete(aRequest) {};
+ this.loadComplete = function loadComplete(aRequest) {};
+ this.frameUpdate = function frameUpdate(aRequest) {};
+ this.discard = function discard(aRequest) {};
+ this.isAnimated = function isAnimated(aRequest) {};
+ this.hasTransparency = function hasTransparency(aRequest) {};
+}
diff --git a/image/test/mochitest/infinite-apng.png b/image/test/mochitest/infinite-apng.png
new file mode 100644
index 0000000000..637dafbc2b
--- /dev/null
+++ b/image/test/mochitest/infinite-apng.png
Binary files differ
diff --git a/image/test/mochitest/infinite.avif b/image/test/mochitest/infinite.avif
new file mode 100644
index 0000000000..a5be1912a8
--- /dev/null
+++ b/image/test/mochitest/infinite.avif
Binary files differ
diff --git a/image/test/mochitest/infinite.webp b/image/test/mochitest/infinite.webp
new file mode 100644
index 0000000000..4219e179b0
--- /dev/null
+++ b/image/test/mochitest/infinite.webp
Binary files differ
diff --git a/image/test/mochitest/invalid.jpg b/image/test/mochitest/invalid.jpg
new file mode 100644
index 0000000000..c677a81e29
--- /dev/null
+++ b/image/test/mochitest/invalid.jpg
@@ -0,0 +1 @@
+notajpg
diff --git a/image/test/mochitest/keep.gif b/image/test/mochitest/keep.gif
new file mode 100644
index 0000000000..e967d6a6dc
--- /dev/null
+++ b/image/test/mochitest/keep.gif
Binary files differ
diff --git a/image/test/mochitest/keep.png b/image/test/mochitest/keep.png
new file mode 100644
index 0000000000..aa3ff74450
--- /dev/null
+++ b/image/test/mochitest/keep.png
Binary files differ
diff --git a/image/test/mochitest/keep.webp b/image/test/mochitest/keep.webp
new file mode 100644
index 0000000000..342982be06
--- /dev/null
+++ b/image/test/mochitest/keep.webp
Binary files differ
diff --git a/image/test/mochitest/lime-anim-100x100-2.svg b/image/test/mochitest/lime-anim-100x100-2.svg
new file mode 100644
index 0000000000..d19d3b0e7e
--- /dev/null
+++ b/image/test/mochitest/lime-anim-100x100-2.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
+ width="100" height="100">
+ <rect width="100%" height="100%" fill="red">
+ <animate attributeName="fill" to="lime" dur="0.1" fill="freeze"/>
+ </rect>
+</svg>
diff --git a/image/test/mochitest/lime-anim-100x100.svg b/image/test/mochitest/lime-anim-100x100.svg
new file mode 100644
index 0000000000..c6584047d0
--- /dev/null
+++ b/image/test/mochitest/lime-anim-100x100.svg
@@ -0,0 +1,7 @@
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
+ width="100" height="100">
+ <rect width="100%" height="100%" fill="red"/>
+ <rect x="-600" width="100%" height="100%" fill="lime">
+ <animate attributeName="x" by="600" dur="0.1" fill="freeze"/>
+ </rect>
+</svg>
diff --git a/image/test/mochitest/lime-css-anim-100x100.svg b/image/test/mochitest/lime-css-anim-100x100.svg
new file mode 100644
index 0000000000..3edbd3eaaf
--- /dev/null
+++ b/image/test/mochitest/lime-css-anim-100x100.svg
@@ -0,0 +1,19 @@
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
+ width="100" height="100">
+ <defs>
+ <style>
+ #myRect {
+ animation-duration: 0.1s;
+ animation-name: fade;
+ animation-fill-mode: forwards;
+ }
+
+ @keyframes fade {
+ 0% { fill-opacity: 0 }
+ 100% { fill-opacity: 1 }
+ }
+ </style>
+ </defs>
+ <rect width="100%" height="100%" fill="red"/>
+ <rect id="myRect" width="100%" height="100%" fill="lime" fill-opacity="0"/>
+</svg>
diff --git a/image/test/mochitest/lime100x100.svg b/image/test/mochitest/lime100x100.svg
new file mode 100644
index 0000000000..8bdec62c1f
--- /dev/null
+++ b/image/test/mochitest/lime100x100.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
+ width="100" height="100">
+ <rect width="100%" height="100%" fill="lime"/>
+</svg>
diff --git a/image/test/mochitest/mochitest.ini b/image/test/mochitest/mochitest.ini
new file mode 100644
index 0000000000..9687c5d8a5
--- /dev/null
+++ b/image/test/mochitest/mochitest.ini
@@ -0,0 +1,184 @@
+[DEFAULT]
+support-files =
+ INT32_MIN.bmp
+ animated1.gif
+ animated1.svg
+ animated2.gif
+ animatedMask.gif
+ animated-gif.gif
+ animated-gif2.gif
+ animated-gif_trailing-garbage.gif
+ animated-gif-finalframe.gif
+ animated-avif.avif
+ animation.svg
+ animationPolling.js
+ bad.jpg
+ big.png
+ blue.gif
+ blue.png
+ bug399925.gif
+ bug468160.sjs
+ bug478398_ONLY.png
+ bug490949-iframe.html
+ bug490949.sjs
+ bug496292-1.sjs
+ bug496292-2.sjs
+ bug496292-iframe-1.html
+ bug496292-iframe-2.html
+ bug496292-iframe-ref.html
+ bug497665-iframe.html
+ bug497665.sjs
+ bug552605.sjs
+ bug657191.sjs
+ bug671906-iframe.html
+ bug671906.sjs
+ bug733553-informant.sjs
+ bug733553.sjs
+ bug767779.sjs
+ bug89419-iframe.html
+ bug89419.sjs
+ bug900200.png
+ bug900200-ref.png
+ bug1132427.html
+ bug1132427.gif
+ bug1180105.sjs
+ bug1180105-waiter.sjs
+ bug1217571-iframe.html
+ bug1217571.jpg
+ bug1319025.png
+ bug1319025-ref.png
+ clear.gif
+ clear.png
+ clear.webp
+ clear.avif
+ clear2.gif
+ clear2.webp
+ clear2-results.gif
+ damon.jpg
+ error-early.png
+ filter-final.svg
+ filter.svg
+ finite-apng.png
+ first-frame-padding.gif
+ green.png
+ green-background.html
+ grey.png
+ ico-bmp-opaque.ico
+ ico-bmp-transparent.ico
+ iframe.html
+ imgutils.js
+ infinite.avif
+ infinite.webp
+ infinite-apng.png
+ invalid.jpg
+ keep.gif
+ keep.png
+ keep.webp
+ lime100x100.svg
+ lime-anim-100x100.svg
+ lime-anim-100x100-2.svg
+ lime-css-anim-100x100.svg
+ mq_dynamic_svg_test.html
+ mq_dynamic_svg_ref.html
+ opaque.bmp
+ purple.gif
+ rainbow.gif
+ red.gif
+ red.png
+ ref-iframe.html
+ restore-previous.gif
+ restore-previous.png
+ rillybad.jpg
+ schrep.png
+ shaver.png
+ short_header.gif
+ source.png
+ transparent.gif
+ transparent.png
+ over.png
+ webcam-simulacrum.sjs
+ 6M-pixels.png
+ 12M-pixels-1.png
+ 12M-pixels-2.png
+
+[test_animated_css_image.html]
+[test_animated_gif.html]
+support-files = child.html
+skip-if =
+ http3
+[test_animation.html]
+[test_canvas_frame_animation.html]
+[test_animation_operators.html]
+[test_animation2.html]
+[test_animSVGImage.html]
+skip-if = os == 'android' || os == 'win' || (os == 'mac' && os_version == '10.15') # Bug 1370784, macosx due to bug 1549058
+[test_animSVGImage2.html]
+skip-if =
+ os == 'win' # Bug 1354561
+ os == 'linux' # Bug 1354561
+ os == 'android' # Bug 1354561
+[test_background_image_anim.html]
+[test_bug399925.html]
+[test_bug435296.html]
+skip-if = true # disabled - See bug 578591
+[test_bug466586.html]
+[test_bug468160.html]
+[test_bug478398.html]
+skip-if = true # disabled - See bug 579139
+[test_bug490949.html]
+[test_bug496292.html]
+skip-if = verify
+[test_bug497665.html]
+[test_bug552605-1.html]
+[test_bug552605-2.html]
+[test_bug553982.html]
+[test_bug601470.html]
+[test_bug614392.html]
+[test_bug657191.html]
+[test_bug671906.html]
+skip-if =
+ http3
+[test_bug733553.html]
+skip-if =
+ verify
+ http3
+[test_bug767779.html]
+[test_bug865919.html]
+[test_bug89419-1.html]
+[test_bug89419-2.html]
+[test_bug1132427.html]
+[test_bug1180105.html]
+skip-if =
+ http3
+[test_bug1217571.html]
+[test_bug1325080.html]
+[test_bullet_animation.html]
+[test_changeOfSource.html]
+[test_changeOfSource2.html]
+[test_discardAnimatedImage.html]
+skip-if =
+ http3
+[test_discardFinishedAnimatedImage.html]
+[test_discardFramesAnimatedImage.html]
+[test_drawDiscardedImage.html]
+[test_error_events.html]
+[test_image_crossorigin_data_url.html]
+[test_has_transparency.html]
+[test_mq_dynamic_svg.html]
+[test_net_failedtoprocess.html]
+skip-if = verify
+[test_removal_ondecode.html]
+[test_removal_onload.html]
+[test_short_gif_header.html]
+[test_staticClone.html]
+[test_svg_animatedGIF.html]
+[test_svg_filter_animation.html]
+[test_synchronized_animation.html]
+disabled = bug 1295501
+[test_undisplayed_iframe.html]
+[test_webcam.html]
+[test_xultree_animation.xhtml]
+allow_xul_xbl = true
+skip-if =
+ http3
+[test_image_cache_notification.html]
diff --git a/image/test/mochitest/mq_dynamic_svg_ref.html b/image/test/mochitest/mq_dynamic_svg_ref.html
new file mode 100644
index 0000000000..bbd4a3e205
--- /dev/null
+++ b/image/test/mochitest/mq_dynamic_svg_ref.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<style>
+iframe { border: none; }
+</style>
+<p>inline</p>
+<svg width="50" height="50">
+ <rect width="50" height="50" fill="green"/>
+</svg>
+<p>iframe</p>
+<iframe src='data:image/svg+xml,
+ <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">
+ <rect width="50" height="50" fill="green"/>
+ </svg>
+' width=50 height=50></iframe>
+<p>img</p>
+<img src='data:image/svg+xml,
+ <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">
+ <rect width="50" height="50" fill="green"/>
+ </svg>
+' width=50 height=50>
+<p>background-image</p>
+<div style='background-image: url("data:image/svg+xml,\
+ <svg xmlns=&apos;http://www.w3.org/2000/svg&apos; width=&apos;50&apos; height=&apos;50&apos;>\
+ <rect width=&apos;50&apos; height=&apos;50&apos; fill=&apos;green&apos;/>\
+ </svg>\
+"); width: 50px; height: 50px;'></div>
+<p>img with nested document</p>
+<img src='data:image/svg+xml,
+ <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">
+ <image href="data:image/svg+xml,
+ &amp;lt;svg xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; width=&amp;quot;50&amp;quot; height=&amp;quot;50&amp;quot;>
+ &amp;lt;rect width=&amp;quot;50&amp;quot; height=&amp;quot;50&amp;quot; fill=&amp;quot;green&amp;quot;/>
+ &amp;lt;/svg>
+ " width="50" height="50"/>
+ </svg>
+' width=50 height=50>
diff --git a/image/test/mochitest/mq_dynamic_svg_test.html b/image/test/mochitest/mq_dynamic_svg_test.html
new file mode 100644
index 0000000000..8acb6d3331
--- /dev/null
+++ b/image/test/mochitest/mq_dynamic_svg_test.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<style>
+@media (prefers-color-scheme: dark) {
+ rect { fill: green; }
+}
+iframe { border: none; }
+</style>
+<p>inline</p>
+<svg width="50" height="50">
+ <rect width="50" height="50" fill="red"/>
+</svg>
+<p>iframe</p>
+<iframe src='data:image/svg+xml,
+ <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">
+ <style>
+ @media (prefers-color-scheme: dark) {
+ rect { fill: green; }
+ }
+ </style>
+ <rect width="50" height="50" fill="red"/>
+ </svg>
+' width=50 height=50></iframe>
+<p>img</p>
+<img src='data:image/svg+xml,
+ <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">
+ <style>
+ @media (prefers-color-scheme: dark) {
+ rect { fill: green; }
+ }
+ </style>
+ <rect width="50" height="50" fill="red"/>
+ </svg>
+' width=50 height=50>
+<p>background-image</p>
+<div style='background-image: url("data:image/svg+xml,\
+ <svg xmlns=&apos;http://www.w3.org/2000/svg&apos; width=&apos;50&apos; height=&apos;50&apos;>\
+ <style>\
+ @media (prefers-color-scheme: dark) {\
+ rect { fill: green; }\
+ }\
+ </style>\
+ <rect width=&apos;50&apos; height=&apos;50&apos; fill=&apos;red&apos;/>\
+ </svg>\
+"); width: 50px; height: 50px;'></div>
+<p>img with nested document</p>
+<img src='data:image/svg+xml,
+ <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">
+ <image href="data:image/svg+xml,
+ &amp;lt;svg xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; width=&amp;quot;50&amp;quot; height=&amp;quot;50&amp;quot;>
+ &amp;lt;style>
+ @media (prefers-color-scheme: dark) {
+ rect { fill: green; }
+ }
+ &amp;lt;/style>
+ &amp;lt;rect width=&amp;quot;50&amp;quot; height=&amp;quot;50&amp;quot; fill=&amp;quot;red&amp;quot;/>
+ &amp;lt;/svg>
+ " width="50" height="50"/>
+ </svg>
+' width=50 height=50>
diff --git a/image/test/mochitest/opaque.bmp b/image/test/mochitest/opaque.bmp
new file mode 100644
index 0000000000..63d3f1c058
--- /dev/null
+++ b/image/test/mochitest/opaque.bmp
Binary files differ
diff --git a/image/test/mochitest/over.png b/image/test/mochitest/over.png
new file mode 100644
index 0000000000..9e957182f7
--- /dev/null
+++ b/image/test/mochitest/over.png
Binary files differ
diff --git a/image/test/mochitest/purple.gif b/image/test/mochitest/purple.gif
new file mode 100644
index 0000000000..79826af205
--- /dev/null
+++ b/image/test/mochitest/purple.gif
Binary files differ
diff --git a/image/test/mochitest/rainbow.gif b/image/test/mochitest/rainbow.gif
new file mode 100644
index 0000000000..a247a80df0
--- /dev/null
+++ b/image/test/mochitest/rainbow.gif
Binary files differ
diff --git a/image/test/mochitest/red.gif b/image/test/mochitest/red.gif
new file mode 100644
index 0000000000..d3c32bae25
--- /dev/null
+++ b/image/test/mochitest/red.gif
Binary files differ
diff --git a/image/test/mochitest/red.png b/image/test/mochitest/red.png
new file mode 100644
index 0000000000..aa9ce25263
--- /dev/null
+++ b/image/test/mochitest/red.png
Binary files differ
diff --git a/image/test/mochitest/ref-iframe.html b/image/test/mochitest/ref-iframe.html
new file mode 100644
index 0000000000..585772c8a9
--- /dev/null
+++ b/image/test/mochitest/ref-iframe.html
@@ -0,0 +1,6 @@
+<html>
+<body bgcolor="gray">
+ <div id="referenceImage"
+ style="height: 40px; width: 40px; background: #2aff00"></div>
+</body>
+</html>
diff --git a/image/test/mochitest/restore-previous.gif b/image/test/mochitest/restore-previous.gif
new file mode 100644
index 0000000000..15ba9ddc48
--- /dev/null
+++ b/image/test/mochitest/restore-previous.gif
Binary files differ
diff --git a/image/test/mochitest/restore-previous.png b/image/test/mochitest/restore-previous.png
new file mode 100644
index 0000000000..09dee63820
--- /dev/null
+++ b/image/test/mochitest/restore-previous.png
Binary files differ
diff --git a/image/test/mochitest/rillybad.jpg b/image/test/mochitest/rillybad.jpg
new file mode 100644
index 0000000000..e2fb1d303f
--- /dev/null
+++ b/image/test/mochitest/rillybad.jpg
Binary files differ
diff --git a/image/test/mochitest/schrep.png b/image/test/mochitest/schrep.png
new file mode 100644
index 0000000000..bcb406387d
--- /dev/null
+++ b/image/test/mochitest/schrep.png
Binary files differ
diff --git a/image/test/mochitest/shaver.png b/image/test/mochitest/shaver.png
new file mode 100644
index 0000000000..ab0b6c7b40
--- /dev/null
+++ b/image/test/mochitest/shaver.png
Binary files differ
diff --git a/image/test/mochitest/short_header.gif b/image/test/mochitest/short_header.gif
new file mode 100644
index 0000000000..70af95ac6d
--- /dev/null
+++ b/image/test/mochitest/short_header.gif
Binary files differ
diff --git a/image/test/mochitest/source.png b/image/test/mochitest/source.png
new file mode 100644
index 0000000000..df1c76dae5
--- /dev/null
+++ b/image/test/mochitest/source.png
Binary files differ
diff --git a/image/test/mochitest/test_animSVGImage.html b/image/test/mochitest/test_animSVGImage.html
new file mode 100644
index 0000000000..a405cdd46b
--- /dev/null
+++ b/image/test/mochitest/test_animSVGImage.html
@@ -0,0 +1,124 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=610419
+-->
+<head>
+ <title>Test for Bug 610419</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=610419">Mozilla Bug 610419</a>
+<p id="display"></p>
+<div id="content">
+ <div id="referenceDiv" style="height: 100px; width: 100px;
+ display: none; background: lime"></div>
+ <img>
+</div>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 610419**/
+
+SimpleTest.requestFlakyTimeout("Pre-existing timeouts when converting from mochitest-chrome");
+SimpleTest.requestCompleteLog();
+SimpleTest.waitForExplicitFinish();
+
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+const gImg = document.getElementsByTagName("img")[0];
+
+var gMyDecoderObserver; // value will be set in main()
+var gReferenceSnapshot; // value will be set in takeReferenceSnapshot()
+var gPollCounter = 0;
+var gIsTestFinished = false;
+var gSVGImages = [
+ "lime-anim-100x100.svg", // SMIL animation
+ "lime-css-anim-100x100.svg" // CSS animation
+]
+var gSVGCurrentImage = 0;
+
+function takeReferenceSnapshot() {
+ // Take a snapshot of the initial (essentially blank) page
+ let blankSnapshot = snapshotWindow(window, false);
+
+ // Show reference div, & take a snapshot
+ let referenceDiv = document.getElementById("referenceDiv");
+ referenceDiv.style.display = "block";
+ gReferenceSnapshot = snapshotWindow(window, false);
+ ok(compareSnapshots(blankSnapshot, gReferenceSnapshot, false)[0],
+ "reference snapshot shouldn't match blank page snapshot");
+
+ // Re-hide reference div, and take another snapshot to be sure it's gone
+ referenceDiv.style.display = "none";
+ let blankSnapshot2 = snapshotWindow(window, false);
+ ok(compareSnapshots(blankSnapshot, blankSnapshot2, true)[0],
+ "reference div should disappear when it becomes display:none");
+}
+
+function loadNextImageAndPoll()
+{
+ setTimeout(myPoll, 1);
+ // kick off image-loading! myPoll handles the rest.
+ gImg.setAttribute("src", gSVGImages[gSVGCurrentImage]);
+}
+
+function myPoll() {
+ gPollCounter++;
+ ok(true, "myPoll called");
+ let currentSnapshot = snapshotWindow(window, false);
+ if (compareSnapshots(currentSnapshot, gReferenceSnapshot, true)[0]) {
+ // SUCCESS!
+ ok(true, "Animated image looks correct, " +
+ "at call #" + gPollCounter + " to myPoll");
+
+ if (++gSVGCurrentImage > gSVGImages.length) {
+ cleanUpAndFinish();
+ } else {
+ loadNextImageAndPoll();
+ }
+ }
+ else {
+ setTimeout(myPoll, 20);
+ }
+}
+
+function failTest() {
+ ok(false, "timing out after " + FAILURE_TIMEOUT + "ms. " +
+ "Animated image still doesn't look correct, " +
+ "after call #" + gPollCounter + " to myPoll");
+ cleanUpAndFinish();
+}
+
+function cleanUpAndFinish() {
+ // On the off chance that failTest and myPoll are triggered
+ // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish.
+ if (gIsTestFinished) {
+ return;
+ }
+ SimpleTest.finish();
+ gIsTestFinished = true;
+}
+
+function main() {
+ takeReferenceSnapshot();
+
+ // We want to test the cold loading behavior, so clear cache in case an
+ // earlier test got our image in there already.
+ clearAllImageCaches();
+
+ loadNextImageAndPoll();
+
+ // In case something goes wrong, fail earlier than mochitest timeout,
+ // and with more information.
+ setTimeout(failTest, FAILURE_TIMEOUT);
+}
+
+window.onload = main;
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_animSVGImage2.html b/image/test/mochitest/test_animSVGImage2.html
new file mode 100644
index 0000000000..0f3ae046c5
--- /dev/null
+++ b/image/test/mochitest/test_animSVGImage2.html
@@ -0,0 +1,124 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=907503
+-->
+<head>
+ <title>Test for Bug 907503</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907503">Mozilla Bug 907503</a>
+<p id="display"></p>
+<div id="content">
+ <div id="referenceDiv" style="height: 100px; width: 100px;
+ display: none; background: lime"></div>
+ <img>
+</div>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 907503**/
+
+SimpleTest.requestFlakyTimeout("Early failure timeout");
+SimpleTest.waitForExplicitFinish();
+
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+const Cc = SpecialPowers.Cc;
+const Ci = SpecialPowers.Ci;
+const gImg = document.getElementsByTagName("img")[0];
+
+var gMyDecoderObserver; // value will be set in main()
+var gReferenceSnapshot; // value will be set in takeReferenceSnapshot()
+var gOnFrameUpdateCounter = 0;
+var gIsTestFinished = false;
+
+
+function takeReferenceSnapshot() {
+ // Take a snapshot of the initial (essentially blank) page
+ let blankSnapshot = snapshotWindow(window, false);
+
+ // Show reference div, & take a snapshot
+ let referenceDiv = document.getElementById("referenceDiv");
+ referenceDiv.style.display = "block";
+ gReferenceSnapshot = snapshotWindow(window, false);
+ ok(compareSnapshots(blankSnapshot, gReferenceSnapshot, false)[0],
+ "reference snapshot shouldn't match blank page snapshot");
+
+ // Re-hide reference div, and take another snapshot to be sure it's gone
+ referenceDiv.style.display = "none";
+ let blankSnapshot2 = snapshotWindow(window, false);
+ ok(compareSnapshots(blankSnapshot, blankSnapshot2, true)[0],
+ "reference div should disappear when it becomes display:none");
+}
+
+function myOnFrameUpdate(aRequest) {
+ if (gIsTestFinished) {
+ return;
+ }
+ gOnFrameUpdateCounter++;
+ ok(true, "myOnFrameUpdate called");
+ let currentSnapshot = snapshotWindow(window, false);
+ if (compareSnapshots(currentSnapshot, gReferenceSnapshot, true)[0]) {
+ // SUCCESS!
+ ok(true, "Animated image looks correct, " +
+ "at call #" + gOnFrameUpdateCounter + " to myOnFrameUpdate");
+ cleanUpAndFinish();
+ }
+}
+
+function failTest() {
+ if (gIsTestFinished) {
+ return;
+ }
+ ok(false, "timing out after " + FAILURE_TIMEOUT + "ms. " +
+ "Animated image still doesn't look correct, " +
+ "after call #" + gOnFrameUpdateCounter + " to myOnFrameUpdate");
+ cleanUpAndFinish();
+}
+
+function cleanUpAndFinish() {
+ // On the off chance that failTest and myOnFrameUpdate are triggered
+ // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish.
+ if (gIsTestFinished) {
+ return;
+ }
+ let imgLoadingContent = SpecialPowers.wrap(gImg);
+ imgLoadingContent.removeObserver(gMyDecoderObserver);
+ SimpleTest.finish();
+ gIsTestFinished = true;
+}
+
+function main() {
+ takeReferenceSnapshot();
+
+ // Create, customize & attach decoder observer
+ var observer = new ImageDecoderObserverStub();
+ observer.frameUpdate = myOnFrameUpdate;
+ gMyDecoderObserver =
+ Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
+ .createScriptedObserver(SpecialPowers.wrapCallbackObject(observer));
+ let imgLoadingContent = SpecialPowers.wrap(gImg);
+ imgLoadingContent.addObserver(gMyDecoderObserver);
+
+ // We want to test the cold loading behavior, so clear cache in case an
+ // earlier test got our image in there already.
+ clearAllImageCaches();
+
+ // kick off image-loading! myOnFrameUpdate handles the rest.
+ gImg.setAttribute("src", "lime-anim-100x100-2.svg");
+
+ // In case something goes wrong, fail earlier than mochitest timeout,
+ // and with more information.
+ setTimeout(failTest, FAILURE_TIMEOUT);
+}
+
+window.onload = main;
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_animated_css_image.html b/image/test/mochitest/test_animated_css_image.html
new file mode 100644
index 0000000000..ca4a47915f
--- /dev/null
+++ b/image/test/mochitest/test_animated_css_image.html
@@ -0,0 +1,223 @@
+<!doctype html>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+<!--
+ scrolling=no is just paranoia to ensure that we don't get invalidations
+ due to scrollbars
+-->
+<iframe scrolling="no" id="iframe"></iframe>
+<script>
+SimpleTest.waitForExplicitFinish();
+
+// We hit an optimized path in WebRender that doesn't cause a repaint on the
+// main thread:
+//
+// https://searchfox.org/mozilla-central/rev/b7f3977978922d44c7d92ae01c0d4cc2baca7bc2/layout/style/ImageLoader.cpp#553
+//
+// So our assertions and polling need to be a bit weaker on WR.
+const kUsingWebRender = SpecialPowers.DOMWindowUtils.layerManagerType.startsWith("WebRender");
+
+let iframe = document.getElementById("iframe");
+let blankSnapshot;
+
+async function assertAnimates(html, getExpectedRepaintedElement) {
+ const kExpectEqual = true;
+ const kNumRetries = kUsingWebRender ? 600 : 30;
+
+ info("testing: " + html);
+
+ {
+ let load = new Promise(resolve => {
+ iframe.addEventListener("load", resolve, { once: true });
+ });
+ iframe.srcdoc = html;
+ await load;
+ }
+
+ // This ensures the MozAfterPaint events come through as expected.
+ await SimpleTest.promiseFocus(iframe.contentWindow);
+
+ let initial = await snapshotWindow(iframe.contentWindow);
+
+ let repaintedElement = getExpectedRepaintedElement(iframe.contentDocument);
+ if (!kUsingWebRender) {
+ // Ensure the painted state is clear before we start polling.
+ SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement);
+ }
+
+ {
+ let [equal, s1 /* , s2, differentPixels, maxDiff */] = compareSnapshots(initial, blankSnapshot, kExpectEqual);
+ ok(!equal, "Initial snapshot shouldn't be blank");
+ info(s1);
+ }
+
+ let foundDifferent = false;
+ let foundInitialAgain = false;
+ for (let i = 0; i < kNumRetries; ++i) {
+ let current = await snapshotWindow(iframe.contentWindow);
+ let [equal, /* s1 */, s2 /* , differentPixels, maxDiff */ ] = compareSnapshots(initial, current, kExpectEqual);
+ if (!foundDifferent && !equal) {
+ ok(true, `Found different image after ${i} retries`);
+ ok(kUsingWebRender || SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement), "Should've repainted the expected element");
+ info(s2);
+ foundDifferent = true;
+ }
+
+ // Ensure that we go back to the initial state (animated1.gif) is an
+ // infinite gif.
+ if (foundDifferent && equal) {
+ ok(true, `Found same image again after ${i} retries`);
+ ok(kUsingWebRender || SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement), "Should've repainted the expected element");
+ foundInitialAgain = true;
+ break;
+ }
+
+ await new Promise(resolve => {
+ if (kUsingWebRender) {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(resolve);
+ });
+ } else {
+ iframe.contentWindow.addEventListener("MozAfterPaint", resolve, { once: true });
+ }
+ });
+ }
+
+ ok(foundDifferent && foundInitialAgain, `Should've found a different snapshot and then an equal one, after ${kNumRetries} retries`);
+}
+
+const kTests = [
+ // Sanity test: background-image on a regular element.
+ {
+ html: `
+ <!doctype html>
+ <style>
+ div {
+ width: 100px;
+ height: 100px;
+ background-image: url(animated1.gif);
+ }
+ </style>
+ <div></div>
+ `,
+ element(doc) {
+ return doc.querySelector("div");
+ },
+ },
+
+ // bug 1627585: content: url()
+ {
+ html: `
+ <!doctype html>
+ <style>
+ div::before {
+ content: url(animated1.gif);
+ }
+ </style>
+ <div></div>
+ `,
+ element(doc) {
+ return doc.querySelector("div");
+ },
+ },
+
+ // bug 1627585: content: url() (on an element directly)
+ {
+ html: `
+ <!doctype html>
+ <style>
+ div {
+ content: url(animated1.gif);
+ }
+ </style>
+ <div></div>
+ `,
+ element(doc) {
+ return doc.querySelector("div");
+ },
+ },
+
+ // bug 1625571: background propagated to canvas.
+ {
+ html: `
+ <!doctype html>
+ <style>
+ body {
+ background-image: url(animated1.gif);
+ }
+ </style>
+ `,
+ element(doc) {
+ return doc.documentElement;
+ },
+ },
+
+ // bug 1719375: CSS animation in SVG image.
+ {
+ html: `
+ <!doctype html>
+ <style>
+ div {
+ width: 100px;
+ height: 100px;
+ background-image: url(animated1.svg);
+ }
+ </style>
+ <div></div>
+ `,
+ element(doc) {
+ return doc.querySelector("div");
+ },
+ },
+
+ // bug 1730834: stopped window.
+ {
+ html: `
+ <!doctype html>
+ <style>
+ div {
+ width: 100px;
+ height: 100px;
+ }
+ </style>
+ <body onload="window.stop(); document.querySelector('div').style.backgroundImage = 'url(animated1.gif)';">
+ <div></div>
+ </body>
+ `,
+ element(doc) {
+ return doc.querySelector("div");
+ },
+ },
+
+ // bug 1731138: Animated mask
+ {
+ html: `
+ <!doctype html>
+ <style>
+ div {
+ width: 100px;
+ height: 100px;
+ background-color: lime;
+ mask-clip: border-box;
+ mask-size: 100% 100%;
+ mask-image: url(animatedMask.gif);
+ }
+ </style>
+ <div></div>
+ `,
+ element(doc) {
+ return doc.querySelector("div");
+ },
+ },
+];
+
+onload = async function() {
+ // First snapshot the blank window.
+ blankSnapshot = await snapshotWindow(iframe.contentWindow);
+
+ for (let { html, element } of kTests)
+ await assertAnimates(html, element);
+
+ SimpleTest.finish();
+}
+</script>
diff --git a/image/test/mochitest/test_animated_gif.html b/image/test/mochitest/test_animated_gif.html
new file mode 100644
index 0000000000..814749b7f0
--- /dev/null
+++ b/image/test/mochitest/test_animated_gif.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Images outside of display port are not decoded</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script src="imgutils.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<div id="scroller" style="height: 300px; overflow: scroll;">
+ <div style="width: 100%; height: 12000px;"></div>
+ <iframe id="iframe"></iframe>
+ <div style="width: 100%; height: 5000px;"></div>
+</div>
+<pre id="test"></pre>
+<script>
+ add_task(async () => {
+ window.addEventListener("message", event => {
+ isnot(event.data, "decodeComplete",
+ "decodeComplete should never be received");
+ });
+
+ await new Promise(resolve => {
+ window.addEventListener("message", event => {
+ if (event.data == "loadComplete") {
+ ok(true, "Got loadComplete");
+ resolve();
+ }
+ }, { once: true });
+
+ const iframe = document.getElementById("iframe");
+ iframe.src = "http://example.org/tests/image/test/mochitest/child.html";
+ });
+
+ const start = Date.now();
+
+ // Waits a second;
+ await SimpleTest.promiseWaitForCondition(() => {
+ return 1000 < (Date.now() - start);
+ });
+
+ ok(true, "decodeComplete didn't receive within a second");
+ });
+
+</script>
+</body>
+</html>
diff --git a/image/test/mochitest/test_animation.html b/image/test/mochitest/test_animation.html
new file mode 100644
index 0000000000..725cd93e85
--- /dev/null
+++ b/image/test/mochitest/test_animation.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=666446
+-->
+<head>
+ <title>Test for Bug 666446 - General Animated GIF Test</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <script type="application/javascript" src="animationPolling.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
+Mozilla Bug 666446: lots of animated gifs swamp us with paint events
+</a>
+<p id="display"></p>
+
+<div id="content">
+ <div id="referenceDiv" style="height: 40px; width: 40px;
+ display: none; background: #2aff00"></div>
+ <div id="animatedImage">
+ <img id="animatedGif" src="animated-gif.gif" style="display: none;">
+ <div id="text-descr"></div>
+ </div>
+ <div id="debug" style="display:none">
+ </div>
+</div>
+<pre id="test">
+<script type="text/javascript">
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+function main()
+{
+ var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
+ 'animatedGif', 'debug');
+ animTest.beginTest();
+}
+
+window.onload = main;
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_animation2.html b/image/test/mochitest/test_animation2.html
new file mode 100644
index 0000000000..1b4e0f94c7
--- /dev/null
+++ b/image/test/mochitest/test_animation2.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=705580
+-->
+<head>
+ <title>Test for Bug 705580 - General Animated GIF Test 2</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <script type="application/javascript" src="animationPolling.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=705580">
+Mozilla Bug 705580: Test animated GIFs that are converted to ImageLayers
+</a>
+<p id="display"></p>
+
+<div id="content">
+ <!--
+ Use will-change: opacity to force a ContainerLayer, and the img as the sole item in the PaintedLayer. It should then
+ be promoted to an ImageLayer.
+ -->
+ <div id="referenceDiv" style="height: 40px; width: 40px;
+ display: none; background: #2aff00;"></div>
+ <div id="animatedImage" style="will-change: opacity;">
+ <img id="animatedGif" src="animated-gif.gif" style="display: none;">
+ <div id="text-descr"></div>
+ </div>
+ <div id="debug" style="display:none">
+ </div>
+</div>
+<pre id="test">
+<script type="text/javascript">
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+function main()
+{
+ var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
+ 'animatedGif', 'debug');
+ animTest.beginTest();
+}
+
+window.onload = main;
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_animation_operators.html b/image/test/mochitest/test_animation_operators.html
new file mode 100644
index 0000000000..faece37053
--- /dev/null
+++ b/image/test/mochitest/test_animation_operators.html
@@ -0,0 +1,168 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=936720
+-->
+<head>
+ <title>Test for Bug 936720</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=936720">Mozilla Bug 936720</a>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 936720 **/
+
+// Because there is no event telling us when an animated image finishes
+// animating, tests for the operators used by animated GIFs and PNGs
+// require that we poll until we get the correct result. A fixed timeout
+// can easily result in intermittent failures on tests running in VMs.
+
+// (Note that we do _not_ poll the reference, so it must not be animated.)
+
+var gTests = [
+ // IMPORTANT NOTE: For these tests, the test and reference are not
+ // snapshotted in the same way. The REFERENCE (second file) is
+ // assumed to be complete when loaded, but we poll the TEST
+ // (first file) until the test passes.
+
+ // Tests of the allowed disposal operators for GIF, APNG and WebP: keep, clear,
+ // and restore previous.
+ "== green-background.html?clear.gif green.png",
+ "== green-background.html?clear.png green.png",
+ "== green-background.html?clear.webp green.png",
+ "== green-background.html?clear.avif green.png",
+ "== keep.gif green.png",
+ "== keep.png green.png",
+ "== keep.webp green.png",
+ "== restore-previous.gif green.png",
+ "== restore-previous.png green.png",
+
+ // Tests of the blending/compositing operators that only APNG supports.
+ "== over.png grey.png",
+ "!= source.png grey.png",
+ "== bug900200.png bug900200-ref.png",
+ "== bug1319025.png bug1319025-ref.png",
+
+ // Test of subframe updates.
+ "== clear2.gif clear2-results.gif",
+ "== clear2.webp clear2-results.gif",
+];
+
+// Maintain a reference count of how many things we're waiting for until
+// we can say the tests are done.
+var gDelayCount = 0;
+function AddFinishDependency()
+ { ++gDelayCount; }
+function RemoveFinishDependency()
+ { if (--gDelayCount == 0) SimpleTest.finish(); }
+
+// We record the maximum number of times we had to look at a test before
+// it switched to the passing state (though we assume it's 10 to start
+// rather than 0 so that we have a reasonable default). Then we make a
+// test "time out" if it takes more than gTimeoutFactor times that
+// amount of time. This allows us to report a test failure rather than
+// making a test failure just show up as a timeout.
+var gMaxPassingTries = 10;
+var gTimeoutFactor = 10;
+
+function takeSnapshot(iframe_element)
+{
+ return snapshotWindow(iframe_element.contentWindow, false);
+}
+
+function passes(op, shot1, shot2)
+{
+ var values = compareSnapshots(shot1, shot2, op == "==");
+ return values[0];
+}
+
+function startTest(i)
+{
+ var testLine = gTests[i];
+ var splitData = testLine.split(" ");
+ var testData =
+ { op: splitData[0], test: splitData[1], reference: splitData[2] };
+ var tries = 0;
+
+ // Maintain state specific to this test in the closure exposed to all
+ // the functions nested inside this one.
+
+ function startIframe(url)
+ {
+ var element = document.createElement("iframe");
+ element.addEventListener("load", handleLoad);
+ // Smaller than normal reftests, but enough for these.
+ element.setAttribute("style", "width: 100px; height: 100px");
+ element.setAttribute("frameborder", "0");
+ element.setAttribute("scrolling", "no");
+ element.src = url;
+ document.body.appendChild(element);
+ function handleLoad(event)
+ {
+ iframe.loaded = true;
+ if (iframe == reference) {
+ reference.snapshot = takeSnapshot(element);
+ }
+ var other = (iframe == test) ? reference : test;
+ if (other.loaded) {
+ setTimeout(checkTest, 100);
+ }
+ }
+ function checkTest()
+ {
+ var test_snapshot = takeSnapshot(test.element);
+ if (passes(testData.op, test_snapshot, reference.snapshot)) {
+ if (tries > gMaxPassingTries) {
+ gMaxPassingTries = tries;
+ }
+ report(true);
+ } else {
+ ++tries;
+ if (tries > gMaxPassingTries * gTimeoutFactor) {
+ info("Giving up after " + tries + " tries, " +
+ "maxp=" + gMaxPassingTries +
+ "fact=" + gTimeoutFactor);
+ report(false);
+ } else {
+ // The animation might not have finished. Try again in 100ms.
+ setTimeout(checkTest, 100);
+ }
+ }
+ }
+ function report(result)
+ {
+ ok(result, "(" + i + ") " +
+ testData.op + " " + testData.test + " " + testData.reference);
+ RemoveFinishDependency();
+ }
+ var iframe = { element, loaded: false };
+
+ return iframe;
+ }
+
+ AddFinishDependency();
+ var test = startIframe(testData.test);
+ var reference = startIframe(testData.reference);
+}
+
+function runTests()
+{
+ // Run the tests.
+ for (var i = 0; i < gTests.length; ++i) {
+ startTest(i);
+ }
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+
+SpecialPowers.pushPrefEnv({"set": [["image.webp.enabled", true]]}, runTests);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_background_image_anim.html b/image/test/mochitest/test_background_image_anim.html
new file mode 100644
index 0000000000..f1aeb6288b
--- /dev/null
+++ b/image/test/mochitest/test_background_image_anim.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=666446
+-->
+<head>
+ <title>Test for Bug 666446 - Animated Background Images</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <script type="application/javascript" src="animationPolling.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
+Mozilla Bug 666446: lots of animated gifs swamp us with paint events
+</a>
+<p id="display"></p>
+<div id="content">
+ <div id="referenceDiv" style="height: 140px; width: 140px;
+ display: none; background: #2aff00"></div>
+ <div id="bgImage" style="height: 140px; width: 140px; background-image: url(animated-gif.gif); display: none;">
+ </div>
+</div>
+<div id="debug" style="display:none"></div>
+<pre id="test">
+<script type="text/javascript">
+
+/** Test for Bug 666446 nsImageLoader/RasterImage**/
+
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+function main() {
+ var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
+ 'bgImage', 'debug');
+ animTest.beginTest();
+}
+
+window.onload = main;
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug1132427.html b/image/test/mochitest/test_bug1132427.html
new file mode 100644
index 0000000000..0ee2872fea
--- /dev/null
+++ b/image/test/mochitest/test_bug1132427.html
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for scrolling selection into view</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// We open a window which contains two copies of the same gif. One at a scaled size, one at the
+// natural image size. We rely on the bug only showing up in the scaled image. The gif has three
+// frames and a delay of 100ms. The first is all white. The second has a very small update area
+// in the upper left, it changes the pixels to slightly off white. The third changes all the
+// pixels to blue. When the bug appears we only update the upper left pixels when looping around
+// from the last frame to the first frame. We compare a middle pixel of the two images to make
+// sure that they are the same at 100ms for a second. If the bug appears then the middle pixel
+// on the scaled image will always be blue and so should not match the middle pixel on the
+// unscaled image which should be white two thirds of the time. If the timers fire at bad times
+// and only fire when both frames are displaying blue we won't be able to detect this bug and the
+// test will pass without testing anything important, but that's not a big deal. That should be
+// rare enough, and the next time the test is run will should do proper testing.
+
+SimpleTest.requestFlakyTimeout("Pre-existing timeouts when converting from mochitest-chrome");
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(openWindow);
+
+var win = null;
+
+function openWindow() {
+ win = window.open("bug1132427.html",
+ "", "scrollbars=yes,toolbar,menubar,width=600,height=800");
+ win.focus();
+}
+
+function doTest() {
+ setTimeout(continueTest, 1000);
+}
+
+function checkPixel(canvas, context, x1, y1, x2, y2) {
+ var pix = context.getImageData(0, 0, canvas.width, canvas.height).data;
+ for (var i = 0; i < 4; i++) {
+ is(pix[4 * (y1 * canvas.width + x1) + i], pix[4 * (y2 * canvas.width + x2) + i], "pixels should match");
+ }
+}
+
+var iterationsLeft = 10;
+
+function continueTest() {
+ // we need to drawWindow the chrome window so we can get a dump of the retained widget layers
+ // if we have to repaint to fulfill this drawWindow request then it will be impossible to
+ // observe the bug
+ // XXX(kmag): This test has not had access to a chrome window since the dawn
+ // of e10s. I'm not sure how accurate the above comment was even before that
+ // point, but it certainly is not accurate now.
+ var topWin = SpecialPowers.wrap(win).top;
+
+ var el = window.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
+ el.width = topWin.innerWidth;
+ el.height = topWin.innerHeight;
+ var ctx = el.getContext("2d");
+ // pass the correct flags so we don't have to flush the retained layers
+ SpecialPowers.wrap(ctx).drawWindow(topWin, 0, 0, topWin.innerWidth, topWin.innerHeight, "rgba(0,0,0,0)",
+ ctx.DRAWWINDOW_USE_WIDGET_LAYERS | ctx.DRAWWINDOW_DRAW_VIEW | ctx.DRAWWINDOW_DRAW_CARET);
+
+ var leftbox = win.document.getElementById("left").getBoundingClientRect();
+ var rightbox = win.document.getElementById("right").getBoundingClientRect();
+ // this is actually chrome on left and right, but in practice we have none so it doesn't matter
+ var chromeleft = win.outerWidth - win.innerWidth;
+ // this is actually chrome on top and bottom, but bottom chrome is usually small to none and we have
+ // 100px to spare in hitting the middle of the image elements (they are 200x200)
+ var chrometop = win.outerHeight - win.innerHeight;
+
+ // compare the middle of the two image elements
+ checkPixel(el, ctx, chromeleft + leftbox.left + Math.floor(leftbox.width/2), chrometop + leftbox.top + Math.floor(leftbox.height/2),
+ chromeleft + rightbox.left + Math.floor(rightbox.width/2), chrometop + rightbox.top + Math.floor(rightbox.height/2));
+
+ iterationsLeft--;
+ if (iterationsLeft > 0) {
+ // now test 100ms later, we should have the next frame of the gif then
+ setTimeout(continueTest, 100);
+ } else {
+ win.close();
+ SimpleTest.finish();
+ }
+}
+</script>
+</pre>
+</body>
+
+</html>
diff --git a/image/test/mochitest/test_bug1180105.html b/image/test/mochitest/test_bug1180105.html
new file mode 100644
index 0000000000..579c8db760
--- /dev/null
+++ b/image/test/mochitest/test_bug1180105.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1180105
+-->
+<head>
+ <title>Test for Bug 1180105</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="initializeOnload()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1180105">Mozilla Bug 1180105</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+const WAITER_URL = "bug1180105-waiter.sjs";
+
+function initializeOnload() {
+ var firstimg = document.createElement('img');
+ firstimg.src = "bug1180105.sjs";
+ document.getElementById('content').appendChild(firstimg);
+
+ waitForFinish();
+}
+
+function waitForFinish() {
+ var loader = document.getElementById("loader");
+ loader.src = WAITER_URL;
+ loader.onload = function() {
+ var img = document.getElementsByTagName('img')[0];
+ ok(img.width > 0, "Image should be loaded by now");
+ SimpleTest.finish();
+ };
+}
+
+</script>
+</pre>
+<div id="content">>
+<iframe id="loader"></iframe>
+</div>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug1217571.html b/image/test/mochitest/test_bug1217571.html
new file mode 100644
index 0000000000..f81fc7c51d
--- /dev/null
+++ b/image/test/mochitest/test_bug1217571.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1217571
+-->
+<head>
+ <title>Test for Bug 1217571</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1217571">Mozilla Bug 1217571</a>
+<p id="display"></p>
+<iframe src="bug1217571-iframe.html"></iframe>
+<iframe src="bug1217571-iframe.html"></iframe>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 614392**/
+
+SimpleTest.waitForExplicitFinish();
+
+window.onload = function() {
+ // Each iframe loads the same image. Both images should share the same
+ // container from the image cache. Check that this holds true.
+ var iframes = document.getElementsByTagName("iframe");
+ var imgs = Array.from(iframes, function (f) {
+ return SpecialPowers.wrap(f.contentDocument.getElementsByTagName("img")[0]);
+ });
+ var containers = imgs.map(function (img) {
+ return img.getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST)
+ .image;
+ });
+
+ ok(SpecialPowers.compare(containers[0], containers[1]),
+ "containers for identical images in different iframes should be identical");
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug1325080.html b/image/test/mochitest/test_bug1325080.html
new file mode 100644
index 0000000000..91dea11173
--- /dev/null
+++ b/image/test/mochitest/test_bug1325080.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1325080
+-->
+<head>
+ <title>Test for Bug 1325080</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1325080">Mozilla Bug 1325080</a>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 1325080 **/
+
+SimpleTest.waitForExplicitFinish();
+
+function createImage() {
+ // This function's code comes from the Acid3 test #72
+ document.open();
+ document.write('<!DOCTYPE html><head><style>img { height: 10px; }</style></head><body><img src="data:image/gif;base64,R0lGODlhAQABAID%2FAMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D" alt="alt-text"></body>');
+ document.close();
+}
+
+window.onload = function() {
+ createImage();
+ SimpleTest.executeSoon(() => {
+ ok(document.images[0].height == 10, "Style should set height of image.");
+ SimpleTest.finish();
+ });
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug399925.html b/image/test/mochitest/test_bug399925.html
new file mode 100644
index 0000000000..ae45479377
--- /dev/null
+++ b/image/test/mochitest/test_bug399925.html
@@ -0,0 +1,102 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=399925
+-->
+<head>
+ <title>Test for Bug 399925</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="imgutils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=399925">Mozilla Bug 399925</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<canvas id="canvas" width="100" height="100"> </canvas>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 399925. **/
+var triggerDiscardingManually = false;
+var pngResults = [];
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+
+window.onload = function() {
+ // It'd be nice to reduce the discard timer here, but unfortunately we only
+ // read that pref on startup. We instead manually trigger discarding on
+ // platforms where the discard timer is too long (which we'll somewhat
+ // arbitrarily define as 'longer than 60 seconds').
+ var expirationMs =
+ SpecialPowers.getIntPref('image.mem.surfacecache.min_expiration_ms');
+ if (expirationMs > 60000) {
+ ok(true, 'Triggering discarding manually because SurfaceCache expiration ' +
+ 'is ' + expirationMs + ' ms');
+ triggerDiscardingManually = true;
+ } else {
+ ok(true, 'Using normal discarding because SurfaceCache expiration ' +
+ 'is ' + expirationMs + ' ms');
+ }
+
+ // Enable discarding for the test.
+ SpecialPowers.pushPrefEnv({
+ 'set':[['image.mem.discardable',true]]
+ }, runTest);
+}
+
+function runTest() {
+ var image = new Image();
+ image.setAttribute("id", "gif");
+
+ // 1. Draw the canvas once on loadComplete
+ // 2. Redraw the canvas and compare the results right on discard
+ addCallbacks(image, drawCanvas, function() {
+ drawCanvas();
+ is(pngResults[0], pngResults[1], "got different rendered results");
+ SimpleTest.finish();
+ });
+
+ image.src = "bug399925.gif";
+ document.getElementById("content").appendChild(image);
+
+ if (triggerDiscardingManually) {
+ var request = SpecialPowers.wrap(image)
+ .getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST);
+ setTimeout(() => request.requestDiscard(), 1000);
+ }
+}
+
+function addCallbacks(anImage, loadCompleteCallback, discardCallback) {
+ var observer = new ImageDecoderObserverStub();
+ observer.discard = function () {
+ imgLoadingContent.removeObserver(scriptedObserver);
+ discardCallback();
+ }
+ observer.loadComplete = loadCompleteCallback;
+ observer = SpecialPowers.wrapCallbackObject(observer);
+
+ var scriptedObserver = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
+ .getService(SpecialPowers.Ci.imgITools)
+ .createScriptedObserver(observer);
+
+ var imgLoadingContent = SpecialPowers.wrap(anImage);
+ imgLoadingContent.addObserver(scriptedObserver);
+}
+
+function drawCanvas() {
+ var canvas = document.getElementById('canvas');
+ var context = canvas.getContext('2d');
+ var gif = document.getElementById('gif');
+
+ context.drawImage(gif, 0, 0);
+ ok(true, "we got through the drawImage call without an exception being thrown");
+ pngResults.push(canvas.toDataURL());
+}
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/image/test/mochitest/test_bug415761.html b/image/test/mochitest/test_bug415761.html
new file mode 100644
index 0000000000..f3bf6c67a8
--- /dev/null
+++ b/image/test/mochitest/test_bug415761.html
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for icon filenames</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+// We want to make sure that moz-icon URIs with non-ascii characters work. To that
+// end, we compare the rendering of an icon without non-ascii characters to that
+// of one that does include such characters.
+
+// First, obtain the file URI to the ourselves:
+var chromeURI = location.href;
+var io = Services.io;
+chromeURI = io.newURI(chromeURI);
+var chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"]
+ .getService(Ci.nsIChromeRegistry);
+var fileURI = chromeReg.convertChromeURL(chromeURI);
+fileURI.QueryInterface(Ci.nsIFileURL);
+var self = fileURI.file;
+
+// Check if the ref or test icon are still hanging around from a previous test
+var testDest = self.parent;
+var refDest = self.parent;
+testDest.append("\u263a.ico");
+refDest.append("bug415761-ref.ico");
+if (testDest.exists()) {
+ testDest.remove(false);
+}
+if (refDest.exists()) {
+ refDest.remove(false);
+}
+
+// Copy the source icon so that we have two identical icons with, one with
+// non-ascii characters in its name.
+var src = self.parent;
+src.append("bug415761.ico");
+src.copyTo(null, testDest.leafName);
+src.copyTo(null, refDest.leafName);
+
+// Now load both icons in an Image() with a moz-icon URI
+var testImage = new Image();
+var refImage = new Image();
+
+var loadedImages = 0;
+testImage.onload = refImage.onload = function() {
+ loadedImages++;
+ if (loadedImages == 2) {
+ finishTest();
+ }
+};
+testImage.onerror = refImage.onerror = function() {
+ testImage.onload = refImage.onload = function() {};
+
+ ok(false, "Icon did not load successfully");
+ SimpleTest.finish();
+};
+
+function finishTest() {
+ ok(true, "Both icons loaded successfully");
+ // Render the reference to a canvas
+ var refCanvas = document.createElement("canvas");
+ refCanvas.setAttribute("height", 32);
+ refCanvas.setAttribute("width", 32);
+ refCanvas.getContext('2d').drawImage(refImage, 0, 0, 32, 32);
+
+ // A blank canvas to compare to to make sure we don't draw nothing.
+ var blankCanvas = document.createElement("canvas");
+ blankCanvas.setAttribute("height", 32);
+ blankCanvas.setAttribute("width", 32);
+
+ // Assert that they should be the different.
+ if (!navigator.userAgent.includes("Windows NT 6.1")) {
+ // Fails on Windows 7 for some reason.
+ assertSnapshots(blankCanvas, refCanvas, false, 0, "blank", "reference icon");
+ }
+
+ // Render the icon with a non-ascii character in its name to a canvas
+ var testCanvas = document.createElement("canvas");
+ testCanvas.setAttribute("height", 32);
+ testCanvas.setAttribute("width", 32);
+ testCanvas.getContext('2d').drawImage(testImage, 0, 0, 32, 32);
+
+ // Assert that they should be the same.
+ assertSnapshots(testCanvas, refCanvas, true, 0, "icon", "reference icon");
+ SimpleTest.finish();
+};
+
+var testURI = io.newFileURI(testDest).spec;
+var refURI = io.newFileURI(refDest).spec;
+testImage.src = "moz-icon:" + testURI;
+refImage.src = "moz-icon:" + refURI;
+
+SimpleTest.registerCleanupFunction(function() {
+ // Remove the copied files if they exist.
+ if (testDest.exists()) {
+ testDest.remove(false);
+ }
+ if (refDest.exists()) {
+ refDest.remove(false);
+ }
+});
+
+</script>
+</pre>
+</body>
+
+</html>
+
diff --git a/image/test/mochitest/test_bug435296.html b/image/test/mochitest/test_bug435296.html
new file mode 100644
index 0000000000..1610410b16
--- /dev/null
+++ b/image/test/mochitest/test_bug435296.html
@@ -0,0 +1,85 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=435296
+-->
+<head>
+ <title>Test for Bug 435296</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=435296">Mozilla Bug 435296</a>
+<img id="testimage" style="display: none;">
+<pre id="test">
+<script type="application/javascript">
+
+// Boilerplate
+SimpleTest.waitForExplicitFinish();
+
+// Assert that discarding isn't enabled, which might make this test go orange.
+ok(!getImagePref(DISCARD_ENABLED_PREF), "discarding should NOT be enabled here");
+
+// We want to make sure d-o-d is enabled, since that's what we're testing
+var oldDODPref = getImagePref(DECODEONDRAW_ENABLED_PREF);
+setImagePref(DECODEONDRAW_ENABLED_PREF, true);
+
+// We're relying on very particular behavior for certain images - clear the
+// image cache.
+clearImageCache();
+
+// In order to work around the effects introduced in bug 512435, we only load
+// the image after window onload fires
+function windowLoadHandler()
+{
+ // Set the source and an onload handler
+ var image = document.getElementById("testimage");
+ image.src = "schrep.png";
+ image.onload = imageLoadHandler;
+}
+
+function imageLoadHandler()
+{
+ // The image is hidden, so it should not be decoded
+ ok(!isFrameDecoded("testimage"), "image should not be decoded");
+
+ // Make the image visible
+ var image = document.getElementById("testimage");
+ image.style.display = "inline";
+
+ // Wait for the image to decode
+ setTimeout(function() {
+ tryToFinish();
+ }, 500);
+}
+
+function tryToFinish()
+{
+ // If it hasn't happened yet, wait longer. If it never happens, this test
+ // will timeout after 300 seconds...
+ if (!isFrameDecoded("testimage")) {
+ setTimeout(function() {
+ tryToFinish();
+ }, 500);
+ return;
+ }
+
+ // By definition, the image is decoded here. Give ourselves a pat on the back.
+ ok(isFrameDecoded("testimage"), "image should be decoded");
+
+ // Restore the decode-on-draw pref
+ setImagePref(DECODEONDRAW_ENABLED_PREF, oldDODPref);
+
+ // All done
+ SimpleTest.finish();
+}
+
+// Set our onload handler, making sure we have focus
+window.onload = SimpleTest.waitForFocus(windowLoadHandler);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug466586.html b/image/test/mochitest/test_bug466586.html
new file mode 100644
index 0000000000..fb900dc2b3
--- /dev/null
+++ b/image/test/mochitest/test_bug466586.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=466586
+-->
+<head>
+ <title>Test for Bug 466586</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<body onload="loadSmall();">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=89419">Mozilla Bug 466586</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <img id="big" src="big.png"/>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+var jsBig = new Image();
+
+// We have loaded the large png with id "big". We want to test if it will be
+// kicked out of the cache and thus have to be reloaded, but to ensure that, we
+// need to get the cache to look at what is there. So we load another image,
+// this one small.
+function loadSmall()
+{
+ // Trivial check, for reference.
+ is(document.getElementById("big").width, 3000,
+ "HTML 'big' image width after page onload()");
+
+ var small = new Image();
+ small.onload = smallLoaded;
+ small.src = "red.png";
+}
+
+function smallLoaded()
+{
+ jsBig.src = document.getElementById("big").src;
+ // Check that it is not needed to wait for onload().
+ is(jsBig.width, 3000, "JS 'big' image width before its onload()");
+ // Check again after onload(), for reference.
+ jsBig.onload = jsBigLoaded;
+}
+
+function jsBigLoaded()
+{
+ is(jsBig.width, 3000, "JS 'big' image width after its onload()");
+
+ SimpleTest.finish();
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug468160.html b/image/test/mochitest/test_bug468160.html
new file mode 100644
index 0000000000..cb33454e1b
--- /dev/null
+++ b/image/test/mochitest/test_bug468160.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=468160
+-->
+<head>
+ <title>Test for Bug 468160</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=468160">Mozilla Bug 468160</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<!-- bug468160.sjs does a simple redirect to a PNG image. As long as this
+ doesn't leak, this test passes. -->
+
+<object data="bug468160.sjs"></object>
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+ok(true, "test passed");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug478398.html b/image/test/mochitest/test_bug478398.html
new file mode 100644
index 0000000000..45ab6acc2f
--- /dev/null
+++ b/image/test/mochitest/test_bug478398.html
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=478398
+-->
+<head>
+ <title>Test for Bug 478398</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="imgutils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=478398">Mozilla Bug 478398</a>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 399925. **/
+var oldTimeoutPref;
+var oldDiscardPref;
+SimpleTest.waitForExplicitFinish();
+window.onload = stage1;
+var imageFilename = "bug478398_ONLY.png";
+
+function stage1()
+{
+ // Get the current pref values
+ oldTimeoutPref = getImagePref(DISCARD_TIMEOUT_PREF);
+ oldDiscardPref = getImagePref(DISCARD_ENABLED_PREF);
+
+ // We're testing discarding here
+ setImagePref(DISCARD_ENABLED_PREF, true);
+
+ // Sets the discard timer to 500 ms (max timeout = 2*500ms = 1s)
+ setImagePref(DISCARD_TIMEOUT_PREF, 500);
+
+ // Create the image _after_ setting the discard timer pref
+ // This image was carefully constructed to make it a "big win" for discarding,
+ // so any reasonable heuristic should still discard it.
+ var image = new Image();
+ image.setAttribute("id", "testimage");
+ image.style.display = "none";
+ image.src = imageFilename;
+
+ // Put the image into the document
+ document.body.appendChild(image);
+
+ // Wait for load, then do stage2
+ image.onload = stage2;
+}
+
+function stage2()
+{
+ // Make sure we're loaded
+ ok(isImageLoaded("testimage"), "image should be loaded");
+
+ // We're loaded - force a synchronous decode
+ forceDecode("testimage");
+
+ // We should be decoded
+ ok(isFrameDecoded("testimage"), "image should be decoded");
+
+ // Wait 1.5 seconds, then finish the test
+ setTimeout(function() {
+ finishTest();;
+ }, 1500);
+
+}
+
+function finishTest()
+{
+ // The image should be discarded by now
+ ok(!isFrameDecoded("testimage"), "image should have been discarded!");
+
+ // Reset the prefs
+ setImagePref(DISCARD_TIMEOUT_PREF, oldTimeoutPref);
+ setImagePref(DISCARD_ENABLED_PREF, oldDiscardPref);
+
+ // Finish the test
+ SimpleTest.finish();
+}
+
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/image/test/mochitest/test_bug490949.html b/image/test/mochitest/test_bug490949.html
new file mode 100644
index 0000000000..8f1b70c8f4
--- /dev/null
+++ b/image/test/mochitest/test_bug490949.html
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=490949
+-->
+<head>
+ <title>Test for Bug 490949</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=490949">Mozilla Bug 490949</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<canvas id="canvas" width="100" height="100"> </canvas>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+var canvas = document.getElementById('canvas');
+var first, second, third;
+
+var RemoteCanvas = function() {
+ this.url = "bug490949-iframe.html";
+};
+
+RemoteCanvas.CANVAS_WIDTH = 100;
+RemoteCanvas.CANVAS_HEIGHT = 100;
+
+RemoteCanvas.prototype.load = function(cb) {
+ this.cb = cb;
+
+ var windowWidth = window.innerWidth - 25;
+ var iframe;
+ iframe = document.createElement("iframe");
+ iframe.id = "test-iframe";
+ iframe.height = "10px";
+ iframe.width = windowWidth + "px";
+ iframe.style.visibility = "hidden";
+ iframe.src = this.url;
+ // Here is where the magic happens... add a listener to the
+ // frame's onload event - it will call handleEvent
+ iframe.addEventListener("load", this, true);
+ // append to the end of the page
+ window.document.body.appendChild(iframe);
+};
+
+RemoteCanvas.prototype.reload = function(cb, force) {
+ this.cb = cb;
+ window.frames[0].location.reload(force);
+}
+
+RemoteCanvas.prototype.handleEvent = function() {
+ // Look back up the iframe by id
+ var ldrFrame = document.getElementById("test-iframe");
+ // Get a reference to the window object you need for the
+ // SpecialPowers.snapshotRect method
+ var remoteWindow = ldrFrame.contentWindow;
+
+ // Draw canvas
+ canvas.style.width = RemoteCanvas.CANVAS_WIDTH + "px";
+ canvas.style.height = RemoteCanvas.CANVAS_HEIGHT + "px";
+ canvas.width = RemoteCanvas.CANVAS_WIDTH;
+ canvas.height = RemoteCanvas.CANVAS_HEIGHT;
+ var windowWidth = window.innerWidth - 25;
+ var windowHeight = window.innerHeight;
+
+ var rect = { left: 0, top: 0, width: windowWidth, height: windowHeight };
+ var snapshot = SpecialPowers.snapshotRect(remoteWindow, rect, "rgb(0,0,0)");
+
+ var ctx = canvas.getContext("2d");
+ ctx.clearRect(0, 0,
+ RemoteCanvas.CANVAS_WIDTH,
+ RemoteCanvas.CANVAS_HEIGHT);
+ ctx.save();
+ ctx.scale(RemoteCanvas.CANVAS_WIDTH / windowWidth,
+ RemoteCanvas.CANVAS_HEIGHT / windowHeight);
+ ctx.drawImage(snapshot, 0, 0);
+ ctx.restore();
+ this.cb();
+};
+
+function checkFirst()
+{
+ first = canvas.toDataURL();
+ remoteCanvas.reload(checkForceReload, true);
+}
+
+function checkForceReload()
+{
+ second = canvas.toDataURL();
+ ok(first != second, "We got the wrong image.");
+ remoteCanvas.reload(checkLazyReload, false);
+}
+
+function checkLazyReload()
+{
+ third = canvas.toDataURL();
+ ok(second != third, "We got the wrong image.");
+ SimpleTest.finish();
+}
+
+var remoteCanvas = new RemoteCanvas();
+remoteCanvas.load(checkFirst);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug496292.html b/image/test/mochitest/test_bug496292.html
new file mode 100644
index 0000000000..7f91539bf3
--- /dev/null
+++ b/image/test/mochitest/test_bug496292.html
@@ -0,0 +1,130 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=496292
+-->
+<head>
+ <title>Test for Bug 496292</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=496292">Mozilla Bug 496292</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<canvas id="canvas" width="100" height="100"> </canvas>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+var canvas = document.getElementById('canvas');
+var first, second, third, ref;
+
+var RemoteCanvas = function(url) {
+ this.url = url;
+};
+
+RemoteCanvas.CANVAS_WIDTH = 100;
+RemoteCanvas.CANVAS_HEIGHT = 100;
+
+RemoteCanvas.prototype.load = function(cb) {
+ this.cb = cb;
+
+ var windowWidth = window.innerWidth - 25;
+ var iframe;
+ iframe = document.createElement("iframe");
+ iframe.id = "test-iframe-" + this.url;
+ iframe.height = "10px";
+ iframe.width = windowWidth + "px";
+ iframe.style.visibility = "hidden";
+ iframe.src = this.url;
+ // Here is where the magic happens... add a listener to the
+ // frame's onload event - it will call handleEvent
+ iframe.addEventListener("load", this, true);
+ // append to the end of the page
+ window.document.body.appendChild(iframe);
+};
+
+RemoteCanvas.prototype.reload = function(cb, force) {
+ this.cb = cb;
+ window.frames[0].location.reload(force);
+}
+
+RemoteCanvas.prototype.handleEvent = function() {
+ // Look back up the iframe by id
+ var ldrFrame = document.getElementById("test-iframe-" + this.url);
+ // Get a reference to the window object you need for the canvas
+ // SpecialPowers.snapshotRect method
+ var remoteWindow = ldrFrame.contentWindow;
+
+ // Draw canvas
+ canvas.style.width = RemoteCanvas.CANVAS_WIDTH + "px";
+ canvas.style.height = RemoteCanvas.CANVAS_HEIGHT + "px";
+ canvas.width = RemoteCanvas.CANVAS_WIDTH;
+ canvas.height = RemoteCanvas.CANVAS_HEIGHT;
+ var windowWidth = window.innerWidth - 25;
+ var windowHeight = window.innerHeight;
+
+ var rect = { left: 0, top: 0, width: windowWidth, height: windowHeight };
+ var snapshot = SpecialPowers.snapshotRect(remoteWindow, rect, "rgb(0,0,0)");
+
+ var ctx = canvas.getContext("2d");
+ ctx.clearRect(0, 0,
+ RemoteCanvas.CANVAS_WIDTH,
+ RemoteCanvas.CANVAS_HEIGHT);
+ ctx.save();
+ ctx.scale(RemoteCanvas.CANVAS_WIDTH / windowWidth,
+ RemoteCanvas.CANVAS_HEIGHT / windowHeight);
+ ctx.drawImage(snapshot, 0, 0);
+ ctx.restore();
+ this.cb();
+};
+
+function loadFirst()
+{
+ ref = canvas.toDataURL();
+
+ var remoteCanvas = new RemoteCanvas("bug496292-iframe-1.html");
+ remoteCanvas.load(checkFirst);
+}
+
+function checkFirst()
+{
+ first = canvas.toDataURL();
+ is(first, ref, "The default Accept header used by image loader is correct");
+
+ SpecialPowers.setCharPref("image.http.accept", "image/png");
+ SpecialPowers.pushPrefEnv({"set": [["image.http.accept", "image/png"]]}, function() {
+ var remoteCanvas = new RemoteCanvas("bug496292-iframe-2.html");
+ remoteCanvas.load(checkSecond);
+ });
+}
+
+function checkSecond()
+{
+ second = canvas.toDataURL();
+ is(second, ref, "The modified Accept header used by image loader is correct");
+
+ SpecialPowers.pushPrefEnv({"clear": [["image.http.accept"]]}, function() {
+ var remoteCanvas = new RemoteCanvas("bug496292-iframe-1.html");
+ remoteCanvas.load(checkThird);
+ });
+}
+
+function checkThird() {
+ third = canvas.toDataURL();
+ is(third, ref, "The Accept header used by image loader should be correctly reset");
+
+ SimpleTest.finish();
+}
+
+var refCanvas = new RemoteCanvas("bug496292-iframe-ref.html");
+refCanvas.load(loadFirst);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug497665.html b/image/test/mochitest/test_bug497665.html
new file mode 100644
index 0000000000..3914e43c64
--- /dev/null
+++ b/image/test/mochitest/test_bug497665.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=497665
+-->
+<head>
+ <title>Test for Bug 497665</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=497665">Mozilla Bug 497665</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+var image1first, image2first, image1second, image2second, image1third, image2third;
+
+SimpleTest.waitForExplicitFinish();
+
+function checkFirst()
+{
+ var iframeelem = document.getElementById('test-iframe');
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+
+ var firstimg = iframeelem.contentDocument.getElementById('image1');
+ var secondimg = iframeelem.contentDocument.getElementById('image2');
+ ctx.drawImage(firstimg, 0, 0);
+ image1first = canvas.toDataURL();
+ ctx.drawImage(secondimg, 0, 0);
+ image2first = canvas.toDataURL();
+
+ ok(image1first == image2first, "We got different images, but shouldn't have.");
+
+ iframeelem.onload = checkForceReload;
+ iframeelem.contentWindow.location.reload(true);
+}
+
+function checkForceReload()
+{
+ var iframeelem = document.getElementById('test-iframe');
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+
+ var firstimg = iframeelem.contentDocument.getElementById('image1');
+ var secondimg = iframeelem.contentDocument.getElementById('image2');
+ ctx.drawImage(firstimg, 0, 0);
+ image1second = canvas.toDataURL();
+ ctx.drawImage(secondimg, 0, 0);
+ image2second = canvas.toDataURL();
+
+ ok(image1second == image2second, "We got different images after a force-reload, but shouldn't have.");
+
+ // Sanity check that we actually reloaded.
+ ok(image1first != image1second, "We got the same images after a force-reload.");
+
+ iframeelem.onload = checkReload;
+ iframeelem.contentWindow.location.reload(false);
+}
+
+function checkReload()
+{
+ var iframeelem = document.getElementById('test-iframe');
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+
+ var firstimg = iframeelem.contentDocument.getElementById('image1');
+ var secondimg = iframeelem.contentDocument.getElementById('image2');
+ ctx.drawImage(firstimg, 0, 0);
+ image1third = canvas.toDataURL();
+ ctx.drawImage(secondimg, 0, 0);
+ image2third = canvas.toDataURL();
+
+ ok(image1third == image2third, "We got different images after a reload, but shouldn't have.");
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+<div id="content"> <!-- style="display: none" -->
+<canvas id="canvas" width="100" height="100"> </canvas>
+<iframe id="test-iframe" src="bug497665-iframe.html" onload="checkFirst()"></iframe>
+</div>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug552605-1.html b/image/test/mochitest/test_bug552605-1.html
new file mode 100644
index 0000000000..271b3599ce
--- /dev/null
+++ b/image/test/mochitest/test_bug552605-1.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=552605
+-->
+<head>
+ <title>Test for Bug 552605</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=552605">Mozilla Bug 552605</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+var first, second;
+
+SimpleTest.waitForExplicitFinish();
+
+function checkFirst()
+{
+ var testimage = document.getElementById('test-image');
+ first = document.createElement('canvas')
+ var ctx = first.getContext('2d');
+ ctx.drawImage(testimage, 0, 0);
+
+ var newimg = new Image();
+ newimg.onload = checkSecond;
+ newimg.src = "bug552605.sjs";
+ document.body.appendChild(newimg);
+}
+
+function checkSecond()
+{
+ var testimage = document.getElementById('test-image');
+ second = document.createElement('canvas')
+ var ctx = second.getContext('2d');
+ ctx.drawImage(testimage, 0, 0);
+
+ // Check that the images are the same, since they're in the same document.
+ var values = compareSnapshots(first, second, true);
+ ok(values[0], "Image should be the same for all loads.");
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+<div id="content"> <!-- style="display: none" -->
+<img src="bug552605.sjs" onload="checkFirst()" id="test-image"></iframe>
+</div>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug552605-2.html b/image/test/mochitest/test_bug552605-2.html
new file mode 100644
index 0000000000..7869a9e481
--- /dev/null
+++ b/image/test/mochitest/test_bug552605-2.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=552605
+-->
+<head>
+ <title>Test for Bug 552605</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=552605">Mozilla Bug 552605</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+var count = 0;
+
+SimpleTest.waitForExplicitFinish();
+
+function check()
+{
+ count++;
+ if (count != 2)
+ return;
+
+ var image1 = document.getElementById('test-image1');
+ var image2 = document.getElementById('test-image2');
+ var first = document.createElement('canvas')
+ var ctx = first.getContext('2d');
+ ctx.drawImage(image1, 0, 0);
+
+ var second = document.createElement('canvas');
+ ctx = second.getContext('2d');
+ ctx.drawImage(image2, 0, 0);
+
+ // Check that the images are the same, since they're in the same document.
+ var values = compareSnapshots(first, second, true);
+ ok(values[0], "Image should be the same for all loads.");
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+<div id="content"> <!-- style="display: none" -->
+<img src="bug552605.sjs" onload="check()" id="test-image1"></iframe>
+<img src="bug552605.sjs" onload="check()" id="test-image2"></iframe>
+</div>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug553982.html b/image/test/mochitest/test_bug553982.html
new file mode 100644
index 0000000000..f7fe58a0af
--- /dev/null
+++ b/image/test/mochitest/test_bug553982.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=553982
+-->
+<head>
+ <title>Test for Bug 553982</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=553982">Mozilla Bug 553982</a>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+var success = false;
+
+// This should fire
+function doError() {
+ success = true;
+}
+
+// This should not fire
+function doLoad() {
+ ok(false, "onload should not fire");
+}
+
+window.onload = function() {
+ ok(success, "onerror should fire");
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+<img src="data:text/html," onerror="doError()" onload="doLoad()" />
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug601470.html b/image/test/mochitest/test_bug601470.html
new file mode 100644
index 0000000000..fdf2d074f8
--- /dev/null
+++ b/image/test/mochitest/test_bug601470.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=601470
+-->
+<head>
+ <title>Test for Bug 601470</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=601470">Mozilla Bug 601470</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <img src="lime100x100.svg" style="width: 100px; height: 100px;">
+ <img src="damon.jpg" style="width: 100px; height: 100px;">
+</div>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 601470 **/
+
+SimpleTest.waitForExplicitFinish();
+
+window.onload = function() {
+ var mgr = SpecialPowers.Cc["@mozilla.org/memory-reporter-manager;1"]
+ .getService(SpecialPowers.Ci.nsIMemoryReporterManager);
+
+ var amount = 0;
+ var handleReport = function(aProcess, aPath, aKind, aUnits, aAmount, aDesc) {
+ amount += aAmount;
+ }
+
+ var finished = function() {
+ ok(amount > 0, "we should be using a nonzero amount of memory");
+ ok(true, "yay, didn't crash!");
+ SimpleTest.finish();
+ }
+
+ mgr.getReports(handleReport, null, finished, null, /* anonymize = */ false);
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug614392.html b/image/test/mochitest/test_bug614392.html
new file mode 100644
index 0000000000..94585ba35e
--- /dev/null
+++ b/image/test/mochitest/test_bug614392.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=614392
+-->
+<head>
+ <title>Test for Bug 614392</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=614392">Mozilla Bug 614392</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <img src="damon.jpg">
+</div>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 614392**/
+
+SimpleTest.waitForExplicitFinish();
+
+window.onload = function() {
+ var img = SpecialPowers.wrap(document.getElementsByTagName("img")[0]);
+ var container = img
+ .getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST)
+ .image;
+
+ container.animationMode =
+ SpecialPowers.Ci.imgIContainer.kDontAnimMode;
+
+ is(container.animationMode,
+ SpecialPowers.Ci.imgIContainer.kDontAnimMode,
+ "yay, our animationMode tweak took effect (and we didn't crash!)");
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug657191.html b/image/test/mochitest/test_bug657191.html
new file mode 100644
index 0000000000..17fcae6c8a
--- /dev/null
+++ b/image/test/mochitest/test_bug657191.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=657191
+-->
+<head>
+ <title>Test for Bug 657191</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=657191">Mozilla Bug 657191</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<!-- bug657191.sjs returns an SVG image with HTTP error code 500.
+ As long as this doesn't crash, this test passes. -->
+ <img src="bug657191.sjs">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 657191 **/
+SimpleTest.waitForExplicitFinish();
+
+window.onload = function() {
+ ok(true, "test passed");
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug671906.html b/image/test/mochitest/test_bug671906.html
new file mode 100644
index 0000000000..82f70f19d6
--- /dev/null
+++ b/image/test/mochitest/test_bug671906.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=671906
+-->
+<head>
+ <title>Test for Bug 671906</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=671906">Mozilla Bug 671906</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+var first, second, third;
+var correct, val1, val2;
+
+SimpleTest.waitForExplicitFinish();
+
+async function snapshotFirst()
+{
+ var iframeelem = document.getElementById('test-iframe');
+ first = await SpecialPowers.wrap(snapshotWindow(iframeelem, false));
+
+ iframeelem.onload = snapshotSecond;
+ iframeelem.src = "http://example.com/tests/image/test/mochitest/bug671906-iframe.html";
+}
+
+async function snapshotSecond()
+{
+ var iframeelem = document.getElementById('test-iframe');
+ second = await SpecialPowers.wrap(snapshotWindow(iframeelem, false));
+
+ // We must have loaded the image again, because the principals for the
+ // loading document are different.
+ [correct, val1, val2] = compareSnapshots(first, second, false);
+ ok(correct, "Image should have changed after changing the iframe's src.");
+
+ iframeelem.onload = snapshotThird;
+ iframeelem.src = "http://mochi.test:8888/tests/image/test/mochitest/bug671906-iframe.html";
+}
+
+async function snapshotThird()
+{
+ var iframeelem = document.getElementById('test-iframe');
+ third = await SpecialPowers.wrap(snapshotWindow(iframeelem, false));
+
+ // We must have loaded the image again, because the principals for the
+ // loading document are different.
+ [correct, val1, val2] = compareSnapshots(second, third, false);
+ ok(correct, "Image should have changed after changing the iframe's src.");
+
+ // We must have looped back to the first image, because the sjs only sends
+ // one of two images.
+ [correct, val1, val2] = compareSnapshots(first, third, true);
+ ok(correct, "Image should be the same on the third load.");
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+<div id="content"> <!-- style="display: none" -->
+<iframe id="test-iframe" src="http://mochi.test:8888/tests/image/test/mochitest/bug671906-iframe.html" onload="snapshotFirst()"></iframe>
+</div>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug733553.html b/image/test/mochitest/test_bug733553.html
new file mode 100644
index 0000000000..6d7ed81019
--- /dev/null
+++ b/image/test/mochitest/test_bug733553.html
@@ -0,0 +1,92 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=733553
+-->
+<head>
+ <title>Test for Bug 733553</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="initializeOnload()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=733553">Mozilla Bug 733553</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+var testIndex = -1;
+var testParts = [
+ [1, "red.png"],
+ [40, "animated-gif2.gif"],
+ [1, "red.png"],
+ [100, "lime100x100.svg"],
+ [100, "lime100x100.svg"],
+ [40, "animated-gif2.gif"],
+ [1, "red.png"],
+ // Note a failure of the next 'red.png' may indicate failure of resniffing on
+ // this part ('shaver.png'); see bug 907575.
+ [177, "shaver.png"],
+ [1, "red.png"],
+ [80, "damon.jpg"],
+ [80, "damon.jpg"],
+ [80, "damon.jpg"],
+ // An invalid image (from bug 787899) that is further delivered with a
+ // "special" bad MIME type that indicates that the necko
+ // multipart/x-mixed-replace parser wasn't able to parse it.
+ // We use a width of 80 because MultipartImage will just drop rillybad.jpg
+ // and re-present damon.jpg.
+ [80, "rillybad.jpg"],
+ [80, "damon.jpg"],
+ // Similarly, we'll drop bad.jpg, so we use damon.jpg's width.
+ [80, "bad.jpg"],
+ [1, "red.png"],
+ // We also drop invalid.jpg, so we use red.png's width.
+ [1, "invalid.jpg"],
+ [40, "animated-gif2.gif"]
+];
+
+// We'll append the part number to this, and tell the informant
+const BASE_URL = "bug733553-informant.sjs?";
+
+function initializeOnload() {
+ var firstimg = document.createElement('img');
+ firstimg.addEventListener("load", imageLoad);
+ firstimg.addEventListener("error", imageLoad);
+ firstimg.alt = "";
+ firstimg.src = "bug733553.sjs";
+ document.getElementById('content').appendChild(firstimg);
+
+ // Really ready for first, but who's counting
+ readyForNext();
+}
+
+function readyForNext() {
+ var loader = document.getElementById("loader");
+ loader.src = BASE_URL + ++testIndex;
+}
+
+function imageLoad(aEvent) {
+ var [width, fileName] = testParts[testIndex];
+ is(aEvent.target.width, width,
+ "Test " + testIndex + " " + fileName + " width correct");
+
+ // Always call readyForNext here, as it's the closest we have to a cleanup
+ readyForNext();
+ if (testParts.length == testIndex) {
+ var firstimg = document.getElementsByTagName('img')[0];
+ firstimg.removeEventListener("load", imageLoad);
+ firstimg.removeEventListener("error", imageLoad);
+ SimpleTest.finish();
+ }
+}
+
+</script>
+</pre>
+<div id="content"> <!-- style="display: none" -->
+<iframe id="loader"></iframe>
+</div>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug767779.html b/image/test/mochitest/test_bug767779.html
new file mode 100644
index 0000000000..ae3fe492cf
--- /dev/null
+++ b/image/test/mochitest/test_bug767779.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=767779
+-->
+<head>
+ <title>Test for Bug 767779</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <script type="application/javascript" src="animationPolling.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=767779">Mozilla Bug 767779</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+const FAILURE_TIMEOUT = 30000; // Fail early after 30 seconds
+
+function main()
+{
+ // referenceDiv's size and color correspond to the last frame of the GIF
+ var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
+ 'animatedGif', 'debug');
+ animTest.beginTest();
+}
+
+window.onload = main;
+</script>
+</pre>
+<div id="content"> <!-- style="display: none" -->
+ <div id="referenceDiv" style="height: 40px; width: 40px;
+ display: none; background: #18ff00;"></div>
+ <div id="animatedImage">
+ <img id="animatedGif" src="bug767779.sjs" style="display: none;"/>
+ <div id="text-descr"></div>
+ </div>
+ <div id="debug" style="display:none">
+ </div>
+</div>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug865919.html b/image/test/mochitest/test_bug865919.html
new file mode 100644
index 0000000000..46686c67d7
--- /dev/null
+++ b/image/test/mochitest/test_bug865919.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=865919
+-->
+<head>
+ <meta charset="UTF-8">
+ <title>Test for Bug 865919</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script type="text/javascript">
+"use strict";
+
+/* Test for Bug 865919:
+ * BMP with height of INT32_MIN should fail to decode.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+var req = new XMLHttpRequest();
+req.onload = function() { CallbackAssert(true, 'Request for file succeeded.'); };
+req.onerror = function() { CallbackAssert(false, 'Request for file failed! Failed to test non-existent file.'); };
+req.open('GET', 'INT32_MIN.bmp');
+req.send(null);
+
+var outstandingCallbacks = 2;
+
+function CallbackAssert(assertVal, failText) {
+ ok(assertVal, failText);
+
+ outstandingCallbacks--;
+ ok(outstandingCallbacks >= 0, '`outstandingCallbacks` should be non-negative.');
+ if (outstandingCallbacks)
+ return;
+
+ // No outstanding callbacks remain, so we're done.
+ SimpleTest.finish();
+}
+
+</script>
+
+<div id='content'>
+ <img src='INT32_MIN.bmp'
+ onerror='CallbackAssert(true, "Got expected onerror for INT32_MIN.bmp")'
+ onload='CallbackAssert(false, "Got unexpected onload for INT32_MIN.bmp")'>
+</div>
+
+</body>
+</html>
+
diff --git a/image/test/mochitest/test_bug89419-1.html b/image/test/mochitest/test_bug89419-1.html
new file mode 100644
index 0000000000..3364dacbfb
--- /dev/null
+++ b/image/test/mochitest/test_bug89419-1.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=89419
+-->
+<head>
+ <title>Test for Bug 89419</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=89419">Mozilla Bug 89419</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+var first, second, third;
+var correct, val1, val2;
+
+SimpleTest.waitForExplicitFinish();
+
+function checkFirst()
+{
+ var iframeelem = document.getElementById('test-iframe');
+ first = snapshotWindow(iframeelem.contentWindow, false);
+
+ iframeelem.onload = checkSecond;
+ iframeelem.contentWindow.location.reload(false);
+}
+
+function checkSecond()
+{
+ var iframeelem = document.getElementById('test-iframe');
+ second = snapshotWindow(iframeelem.contentWindow, false);
+
+ // Check that we actually reloaded.
+ [correct, val1, val2] = compareSnapshots(first, second, false);
+ ok(correct, "Image should have changed after the first reload.");
+
+ iframeelem.onload = checkThird;
+ iframeelem.contentWindow.location.reload(false);
+}
+
+function checkThird()
+{
+ var iframeelem = document.getElementById('test-iframe');
+ third = snapshotWindow(iframeelem.contentWindow, false);
+
+ // Check that we actually reloaded.
+ [correct, val1, val2] = compareSnapshots(second, third, false);
+ ok(correct, "Image should have changed after the second reload.");
+
+ // Make sure we looped back to the first image.
+ [correct, val1, val2] = compareSnapshots(first, third, true);
+ ok(correct, "Third image should match first image.");
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+<div id="content"> <!-- style="display: none" -->
+<iframe id="test-iframe" src="bug89419-iframe.html" onload="checkFirst()"></iframe>
+</div>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bug89419-2.html b/image/test/mochitest/test_bug89419-2.html
new file mode 100644
index 0000000000..25861b9179
--- /dev/null
+++ b/image/test/mochitest/test_bug89419-2.html
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=89419
+-->
+<head>
+ <title>Test for Bug 89419</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=89419">Mozilla Bug 89419</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+var first, second, third;
+var correct, val1, val2;
+
+SimpleTest.waitForExplicitFinish();
+
+function checkFirst()
+{
+ var iframeelem = document.getElementById('test-iframe');
+ first = snapshotWindow(iframeelem.contentWindow, false);
+
+ iframeelem.onload = checkSecond;
+ // eslint-disable-next-line no-self-assign
+ iframeelem.contentWindow.location.href = iframeelem.contentWindow.location.href;
+}
+
+function checkSecond()
+{
+ var iframeelem = document.getElementById('test-iframe');
+ second = snapshotWindow(iframeelem.contentWindow, false);
+
+ // Check that we actually reloaded.
+ [correct, val1, val2] = compareSnapshots(first, second, false);
+ ok(correct, "Image should have changed after the first reload.");
+
+ iframeelem.onload = checkThird;
+ // eslint-disable-next-line no-self-assign
+ iframeelem.contentWindow.location.href = iframeelem.contentWindow.location.href;
+}
+
+function checkThird()
+{
+ var iframeelem = document.getElementById('test-iframe');
+ third = snapshotWindow(iframeelem.contentWindow, false);
+
+ // Check that we actually reloaded.
+ [correct, val1, val2] = compareSnapshots(second, third, false);
+ ok(correct, "Image should have changed after the second reload.");
+
+ // Make sure we looped back to the first image.
+ [correct, val1, val2] = compareSnapshots(first, third, true);
+ ok(correct, "Third image should match first image.");
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+<div id="content"> <!-- style="display: none" -->
+<iframe id="test-iframe" src="bug89419-iframe.html" onload="checkFirst()"></iframe>
+</div>
+</body>
+</html>
diff --git a/image/test/mochitest/test_bullet_animation.html b/image/test/mochitest/test_bullet_animation.html
new file mode 100644
index 0000000000..7e39898a4f
--- /dev/null
+++ b/image/test/mochitest/test_bullet_animation.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=666446
+-->
+<head>
+ <title>Test for Bug 666446 - Animated Bullets</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <script type="application/javascript" src="animationPolling.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <style>
+ li { color: transparent }
+ </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
+Mozilla Bug 666446: lots of animated gifs swamp us with paint events
+</a>
+<p id="display"></p>
+
+<div id="content">
+ <div id="cleanDiv" style="display: none;">
+ <ul>
+ <li></li>
+ </ul>
+ </div>
+ <div id="referenceDiv" style="display: none;">
+ <ul>
+ <li style="list-style-image: url(animated-gif-finalframe.gif);"></li>
+ </ul>
+ </div>
+ <div id="animatedImage" style="display: none;">
+ <ul>
+ <li style="list-style-image: url(animated-gif.gif);"></li>
+ </ul>
+ </div>
+ <div id="text-descr"></div>
+ <div id="debug" style="display:none">
+ </div>
+</div>
+<pre id="test">
+<script type="text/javascript">
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+function main()
+{
+ var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
+ 'animatedImage', 'debug', 'cleanDiv',
+ 'animated-gif-finalframe.gif');
+ animTest.beginTest();
+}
+
+window.onload = main;
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_canvas_frame_animation.html b/image/test/mochitest/test_canvas_frame_animation.html
new file mode 100644
index 0000000000..c2820b3a66
--- /dev/null
+++ b/image/test/mochitest/test_canvas_frame_animation.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>Test for bug 1619245 - animated image as canvas background</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+<script src="imgutils.js"></script>
+<script src="animationPolling.js"></script>
+<!-- Intentionally not including SimpleTest.css as that sets the background of the root -->
+<body id="body" style="background-image: url(animated-gif.gif); display: none; overflow: hidden;">
+ <div id="reference" style="background-image: url(animated-gif-finalframe.gif); display: none; width: 100vw; height: 100vh;"></div>
+ <div id="clean" style="display: none; width: 100vw; height: 100vh;"></div>
+ <div id="debug" style="display: none"></div>
+</body>
+<script>
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+window.onload = function() {
+ // first move the reference outside of the <body>, so that the test can properly show it.
+ document.documentElement.appendChild(document.getElementById("reference"));
+ document.documentElement.appendChild(document.getElementById("debug"));
+ document.documentElement.appendChild(document.getElementById("clean"));
+ var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'reference', 'body', 'debug', 'clean', 'animated-gif.gif');
+ animTest.beginTest();
+}
+</script>
diff --git a/image/test/mochitest/test_changeOfSource.html b/image/test/mochitest/test_changeOfSource.html
new file mode 100644
index 0000000000..f557a3a140
--- /dev/null
+++ b/image/test/mochitest/test_changeOfSource.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=666446
+-->
+<head>
+ <title>Test for Bug 666446 - Change of Source (1st Version)</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <script type="application/javascript" src="animationPolling.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
+Mozilla Bug 666446: lots of animated gifs swamp us with paint events
+</a>
+<p id="display"></p>
+
+<div id="content">
+ <div id="referenceDiv" style="height: 40px; width: 40px;
+ display: none; background: #2aff00;">
+ </div>
+ <div id="animatedImage">
+ <img id='animatedGif' src="animated-gif.gif" style="display: none;">
+ </div>
+ <div id="text-descr"></div>
+ <div id="debug" style="display:none">
+ </div>
+</div>
+<pre id="test">
+<script type="text/javascript">
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+var gAnimTest;
+var gIntervalId;
+
+function initSecondTest() {
+ document.getElementById('debug').style.display = 'none';
+ document.getElementById('referenceDiv').style.background = "#9600ff";
+ document.getElementById('animatedGif').setAttribute('src',
+ 'animated-gif2.gif');
+ document.getElementById('animatedGif').style.display = 'none';
+ var secondTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
+ 'animatedGif', 'debug', '', '', false);
+ secondTest.beginTest();
+}
+
+function main()
+{
+ gAnimTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
+ 'animatedGif', 'debug', '', '', false,
+ initSecondTest);
+ gAnimTest.beginTest();
+
+}
+
+window.onload = main;
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_changeOfSource2.html b/image/test/mochitest/test_changeOfSource2.html
new file mode 100644
index 0000000000..e3db345470
--- /dev/null
+++ b/image/test/mochitest/test_changeOfSource2.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=666446
+-->
+<head>
+ <title>Test for Bug 691792 - Change of Source (2nd Version)</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <script type="application/javascript" src="animationPolling.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=691792">
+Mozilla Bug 691792: Change of src attribute for animated gifs no longer works as expected
+</a>
+<p id="display"></p>
+
+<div id="content">
+ <div id="animatedImage">
+ <img id='animatedGif' src="purple.gif" style="display: none;">
+ </div>
+ <div id="text-descr"></div>
+ <div id="debug" style="display:none">
+ </div>
+</div>
+<pre id="test">
+<script type="text/javascript">
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+var gAnimTest;
+var gIntervalId;
+
+function main()
+{
+ gAnimTest = new AnimationTest(20, FAILURE_TIMEOUT, 'animated-gif2.gif',
+ 'animatedGif', 'debug', '', 'animated-gif2.gif',
+ false);
+ gAnimTest.beginTest();
+}
+
+window.onload = main;
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_discardAnimatedImage.html b/image/test/mochitest/test_discardAnimatedImage.html
new file mode 100644
index 0000000000..d2aad380e0
--- /dev/null
+++ b/image/test/mochitest/test_discardAnimatedImage.html
@@ -0,0 +1,218 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=686905
+-->
+<head>
+ <title>Test that animated images can be discarded</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="text/javascript" src="imgutils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=686905">Mozilla Bug 686905</a>
+<p id="display"></p>
+<div id="content">
+ <div id="container">
+ <canvas id="canvas" width="100" height="100"></canvas>
+ <img id="infinitepng" src="infinite-apng.png">
+ <img id="infinitegif" src="animated1.gif">
+ <img id="infinitewebp" src="infinite.webp">
+ <img id="infiniteavif" src="infinite.avif">
+ <img id="finitepng" src="restore-previous.png">
+ <img id="finitegif" src="animated-gif.gif">
+ <img id="finitewebp" src="keep.webp">
+ <img id="finiteavif" src="animated-avif.avif">
+ </div>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 686905. **/
+SimpleTest.waitForExplicitFinish();
+
+var gFinished = false;
+
+var gNumDiscards = 0;
+
+window.onload = function() {
+ // Enable discarding for the test.
+ SpecialPowers.pushPrefEnv({
+ 'set':[['image.mem.discardable',true],
+ ['image.webp.enabled',true],
+ ['image.avif.sequence.enabled',true]]
+ }, runTest);
+}
+
+var gImgs = ['infinitepng', 'infinitegif', 'infinitewebp', 'infiniteavif',
+ 'finitepng', 'finitegif', 'finitewebp', 'finiteavif'];
+// If we are currently counting frame updates.
+var gCountingFrameUpdates = false;
+// The number of frame update notifications for the images in gImgs that happen
+// after discarding. (The last two images are finite looping so we don't expect
+// them to get incremented but it's possible if they don't finish their
+// animation before we discard them.)
+var gNumFrameUpdates = [0, 0, 0, 0, 0, 0];
+// The last snapshot of the image. Used to check that the image actually changes.
+var gLastSnapShot = [null, null, null, null, null, null];
+// Number of observed changes in the snapshot.
+var gNumSnapShotChanges = [0, 0, 0, 0, 0, 0];
+// If we've removed the observer.
+var gRemovedObserver = [false, false, false, false, false, false];
+
+// 2 would probably be a good enough test, we arbitrarily choose 4.
+var kNumFrameUpdatesToExpect = 4;
+
+function runTest() {
+ var animatedDiscardable =
+ SpecialPowers.getBoolPref('image.mem.animated.discardable');
+ if (!animatedDiscardable) {
+ ok(true, "discarding of animated images is disabled, nothing to test");
+ SimpleTest.finish();
+ return;
+ }
+
+ setTimeout(step2, 0);
+}
+
+function step2() {
+ // Draw the images to canvas to force them to be decoded.
+ for (let i = 0; i < gImgs.length; i++) {
+ drawCanvas(document.getElementById(gImgs[i]));
+ }
+
+ for (let i = 0; i < gImgs.length; i++) {
+ addCallbacks(document.getElementById(gImgs[i]), i);
+ }
+
+ setTimeout(step3, 0);
+}
+
+function step3() {
+ document.getElementById("container").style.display = "none";
+ document.documentElement.offsetLeft; // force that style to take effect
+
+ for (var i = 0; i < gImgs.length; i++) {
+ requestDiscard(document.getElementById(gImgs[i]));
+ }
+
+ // the discard observers will call step4
+}
+
+function step4() {
+ gCountingFrameUpdates = true;
+ document.getElementById("container").style.display = "";
+
+ // Draw the images to canvas to force them to be decoded again.
+ for (var i = 0; i < gImgs.length; i++) {
+ drawCanvas(document.getElementById(gImgs[i]));
+ }
+}
+
+function checkIfFinished() {
+ if (gFinished) {
+ return;
+ }
+
+ if ((gNumFrameUpdates[0] >= kNumFrameUpdatesToExpect) &&
+ (gNumFrameUpdates[1] >= kNumFrameUpdatesToExpect) &&
+ (gNumFrameUpdates[2] >= kNumFrameUpdatesToExpect) &&
+ (gNumSnapShotChanges[0] >= kNumFrameUpdatesToExpect) &&
+ (gNumSnapShotChanges[1] >= kNumFrameUpdatesToExpect) &&
+ (gNumSnapShotChanges[2] >= kNumFrameUpdatesToExpect)) {
+ ok(true, "got expected frame updates");
+ gFinished = true;
+ SimpleTest.finish();
+ }
+}
+
+// arrayIndex is the index into the arrays gNumFrameUpdates and gNumDecodes
+// to increment when a frame update notification is received.
+function addCallbacks(anImage, arrayIndex) {
+ var observer = new ImageDecoderObserverStub();
+ observer.discard = function () {
+ gNumDiscards++;
+ ok(true, "got image discard");
+ if (arrayIndex >= 3) {
+ // The last two images are finite, so we don't expect any frame updates,
+ // this image is done the test, so remove the observer.
+ if (!gRemovedObserver[arrayIndex]) {
+ gRemovedObserver[arrayIndex] = true;
+ imgLoadingContent.removeObserver(scriptedObserver);
+ }
+ }
+ if (gNumDiscards == gImgs.length) {
+ step4();
+ }
+ };
+ observer.frameUpdate = function () {
+ if (!gCountingFrameUpdates) {
+ return;
+ }
+
+ // Do this off a setTimeout since nsImageLoadingContent uses a scriptblocker
+ // when it notifies us and calling drawWindow can call will paint observers
+ // which can dispatch a scrollport event, and events assert if dispatched
+ // when there is a scriptblocker.
+ setTimeout(function () {
+ gNumFrameUpdates[arrayIndex]++;
+
+ var r = document.getElementById(gImgs[arrayIndex]).getBoundingClientRect();
+ var snapshot = snapshotRect(window, r, "rgba(0,0,0,0)");
+ if (gLastSnapShot[arrayIndex] != null) {
+ if (snapshot.toDataURL() != gLastSnapShot[arrayIndex].toDataURL()) {
+ gNumSnapShotChanges[arrayIndex]++;
+ }
+ }
+ gLastSnapShot[arrayIndex] = snapshot;
+
+ if (gNumFrameUpdates[arrayIndex] >= kNumFrameUpdatesToExpect &&
+ gNumSnapShotChanges[arrayIndex] >= kNumFrameUpdatesToExpect) {
+ if (!gRemovedObserver[arrayIndex]) {
+ gRemovedObserver[arrayIndex] = true;
+ imgLoadingContent.removeObserver(scriptedObserver);
+ }
+ }
+ if (!gFinished) {
+ // because we do this in a setTimeout we can have several in flight
+ // so don't call ok if we've already finished.
+ ok(true, "got frame update");
+ }
+ checkIfFinished();
+ }, 0);
+ };
+ observer = SpecialPowers.wrapCallbackObject(observer);
+
+ var scriptedObserver = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
+ .getService(SpecialPowers.Ci.imgITools)
+ .createScriptedObserver(observer);
+
+ var imgLoadingContent = SpecialPowers.wrap(anImage);
+ imgLoadingContent.addObserver(scriptedObserver);
+}
+
+function requestDiscard(anImage) {
+ var request = SpecialPowers.wrap(anImage)
+ .getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST);
+ setTimeout(() => request.requestDiscard(), 0);
+}
+
+function drawCanvas(anImage) {
+ var canvas = document.getElementById('canvas');
+ var context = canvas.getContext('2d');
+
+ context.clearRect(0,0,100,100);
+ var cleared = canvas.toDataURL();
+
+ context.drawImage(anImage, 0, 0);
+ ok(true, "we got through the drawImage call without an exception being thrown");
+
+ ok(cleared != canvas.toDataURL(), "drawImage drew something");
+}
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/image/test/mochitest/test_discardFinishedAnimatedImage.html b/image/test/mochitest/test_discardFinishedAnimatedImage.html
new file mode 100644
index 0000000000..190cb1d1a0
--- /dev/null
+++ b/image/test/mochitest/test_discardFinishedAnimatedImage.html
@@ -0,0 +1,144 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test that img.decode works on finished, discarded animated images</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="text/javascript" src="imgutils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1629490">Mozilla Bug 1629490</a>
+<div id="container">
+ <img id="finitepng" src="finite-apng.png">
+</div>
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+window.onload = runTest;
+
+let discardCallback = undefined;
+let frameUpdateCallback = undefined;
+
+async function runTest() {
+ const kUsingWebRender = SpecialPowers.DOMWindowUtils.layerManagerType.startsWith("WebRender");
+
+ let img = document.getElementById("finitepng");
+
+ await img.decode();
+
+ while (!isItGreen(img)) {
+ // We hit an optimized path in WebRender that doesn't cause a repaint on the
+ // main thread and doesn't seem to send MozAfterPaints.
+ //
+ // https://searchfox.org/mozilla-central/rev/b7f3977978922d44c7d92ae01c0d4cc2baca7bc2/layout/style/ImageLoader.cpp#553
+ await new Promise(resolve => {
+ if (kUsingWebRender) {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(resolve);
+ });
+ } else {
+ window.addEventListener("MozAfterPaint", resolve, { once: true });
+ }
+ });
+ }
+
+ addCallbacks(img);
+
+ let iterationsLeft = 26;
+ while (iterationsLeft > 0) {
+
+ let discardPromise = new Promise(resolve => {
+ discardCallback = resolve;
+ });
+
+ document.getElementById("container").style.display = "none";
+ document.documentElement.offsetLeft; // force that style to take effect
+ requestDiscard(img);
+
+ await new Promise(resolve => {requestAnimationFrame(() => { requestAnimationFrame(resolve); }); });
+
+ await discardPromise;
+ await new Promise(resolve => {requestAnimationFrame(() => { requestAnimationFrame(resolve); }); });
+
+ let waitForFrameUpdate = new Promise(resolve => {
+ frameUpdateCallback = resolve;
+ });
+
+ document.getElementById("container").style.display = "";
+ document.documentElement.offsetLeft; // force that style to take effect
+
+ await img.decode();
+
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ await waitForFrameUpdate;
+
+ ok(isItGreen(img), "should be green");
+
+ iterationsLeft--;
+ await new Promise(resolve => {requestAnimationFrame(() => { requestAnimationFrame(resolve); }); });
+
+ }
+
+ removeObserver(img);
+ SimpleTest.finish();
+}
+
+function isItGreen(img) {
+ let rect = img.getBoundingClientRect();
+ let r = {left: rect.left + 5, top: rect.top + 5, width: 5, height: 5};
+ let c = SpecialPowers.snapshotWindowWithOptions(window, r);
+ let d = c.getContext('2d').getImageData(0,0,5,5).data;
+ let isGreen = true;
+ for (let i = 0; i < 5*5; i++) {
+ if (d[4*i] != 0 || d[4*i + 1] != 128 || d[4*i + 2] != 0 || d[4*i + 3] != 255) {
+ isGreen = false;
+ }
+ }
+ return isGreen;
+}
+
+
+let scriptedObserver = undefined;
+let imgLoadingContent = undefined;
+function addCallbacks(anImage) {
+ var observer = new ImageDecoderObserverStub();
+ observer.discard = function () {
+ if (discardCallback != undefined) {
+ let localDiscardCallback = discardCallback;
+ discardCallback = undefined;
+ setTimeout(localDiscardCallback, 0);
+ }
+ };
+ observer.frameUpdate = function () {
+ if (frameUpdateCallback != undefined) {
+ let localFrameUpdateCallback = frameUpdateCallback;
+ frameUpdateCallback = undefined;
+ setTimeout(localFrameUpdateCallback, 0);
+ }
+ };
+ observer = SpecialPowers.wrapCallbackObject(observer);
+
+ scriptedObserver = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
+ .getService(SpecialPowers.Ci.imgITools)
+ .createScriptedObserver(observer);
+
+ imgLoadingContent = SpecialPowers.wrap(anImage);
+ imgLoadingContent.addObserver(scriptedObserver);
+}
+
+function removeObserver(anImage) {
+ imgLoadingContent.removeObserver(scriptedObserver);
+}
+
+function requestDiscard(anImage) {
+ var request = SpecialPowers.wrap(anImage)
+ .getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST);
+ setTimeout(() => request.requestDiscard(), 0);
+}
+
+</script>
+</body>
+</html>
diff --git a/image/test/mochitest/test_discardFramesAnimatedImage.html b/image/test/mochitest/test_discardFramesAnimatedImage.html
new file mode 100644
index 0000000000..2e95e6203b
--- /dev/null
+++ b/image/test/mochitest/test_discardFramesAnimatedImage.html
@@ -0,0 +1,268 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=523950
+-->
+<head>
+ <title>Test that animated images can discard frames and redecode</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="text/javascript" src="imgutils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=523950">Mozilla Bug 523950</a>
+<p id="display"></p>
+<div id="content">
+ <div id="container">
+ <canvas id="canvas" width="100" height="100"></canvas>
+ <img id="rainbow.gif"/>
+ </div>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 523950. **/
+SimpleTest.waitForExplicitFinish();
+
+var gFinished = false;
+
+var gNumOnloads = 0;
+
+var gNumDiscards = 0;
+
+window.onload = function() {
+ // Enable minimal frame discard thresholds for the test.
+ SpecialPowers.pushPrefEnv({
+ 'set':[['image.animated.decode-on-demand.threshold-kb',0],
+ ['image.animated.decode-on-demand.batch-size',1],
+ ['image.mem.discardable',true],
+ ['image.mem.animated.discardable',true]]
+ }, runTest);
+}
+
+var gImgs = ['rainbow.gif'];
+// If we are currently counting frame updates.
+var gCountingFrameUpdates = false;
+// The number of frame update notifications for the images in gImgs that happen
+// after discarding. (The last two images are finite looping so we don't expect
+// them to get incremented but it's possible if they don't finish their
+// animation before we discard them.)
+var gNumFrameUpdates = [0];
+// The last snapshot of the image. Used to check that the image actually changes.
+var gLastSnapShot = [null];
+// Number of observed changes in the snapshot.
+var gNumSnapShotChanges = [0];
+// If we've removed the observer.
+var gRemovedObserver = [false];
+
+// rainbow.gif has 9 frames, so we choose arbitrarily 22 to include two loops.
+var kNumFrameUpdatesToExpect = 22;
+
+function runTest() {
+ var thresholdKb =
+ SpecialPowers.getIntPref('image.animated.decode-on-demand.threshold-kb');
+ var batchSize =
+ SpecialPowers.getIntPref('image.animated.decode-on-demand.batch-size');
+ var discardable =
+ SpecialPowers.getBoolPref('image.mem.discardable');
+ var animDiscardable =
+ SpecialPowers.getBoolPref('image.mem.animated.discardable');
+ if (thresholdKb > 0 || batchSize > 1 || !discardable || !animDiscardable) {
+ ok(true, "discarding frames of animated images is disabled, nothing to test");
+ SimpleTest.finish();
+ return;
+ }
+
+ setTimeout(step2, 0);
+}
+
+function step2() {
+ // Only set the src after setting the pref.
+ for (var i = 0; i < gImgs.length; i++) {
+ var elm = document.getElementById(gImgs[i]);
+ elm.src = gImgs[i];
+ elm.onload = checkIfLoaded;
+ }
+}
+
+function step3() {
+ // Draw the images to canvas to force them to be decoded.
+ for (let i = 0; i < gImgs.length; i++) {
+ drawCanvas(document.getElementById(gImgs[i]));
+ }
+
+ for (let i = 0; i < gImgs.length; i++) {
+ addCallbacks(document.getElementById(gImgs[i]), i);
+ }
+
+ setTimeout(step4, 0);
+}
+
+function step4() {
+ ok(true, "now accepting frame updates");
+ gCountingFrameUpdates = true;
+}
+
+function step5() {
+ ok(true, "discarding images");
+
+ document.getElementById("container").style.display = "none";
+ document.documentElement.offsetLeft; // force that style to take effect
+
+ // Reset our state to let us do it all again after discarding.
+ resetState();
+
+ // Draw the images to canvas to force them to be decoded.
+ for (var i = 0; i < gImgs.length; i++) {
+ requestDiscard(document.getElementById(gImgs[i]));
+ }
+
+ // the discard observers will call step6
+}
+
+function step6() {
+ // Repeat the cycle now that we discarded everything.
+ ok(gNumDiscards >= gImgs.length, "discard complete, restarting animations");
+ document.getElementById("container").style.display = "";
+
+ // Draw the images to canvas to force them to be decoded.
+ for (var i = 0; i < gImgs.length; i++) {
+ drawCanvas(document.getElementById(gImgs[i]));
+ }
+
+ setTimeout(step4, 0);
+}
+
+function checkIfLoaded() {
+ ++gNumOnloads;
+ if (gNumOnloads != gImgs.length) {
+ return;
+ }
+
+ ok(true, "got onloads");
+ setTimeout(step3, 0);
+}
+
+function resetState() {
+ gFinished = false;
+ gCountingFrameUpdates = false;
+ for (let i = 0; i < gNumFrameUpdates.length; ++i) {
+ gNumFrameUpdates[i] = 0;
+ }
+ for (let i = 0; i < gNumSnapShotChanges.length; ++i) {
+ gNumSnapShotChanges[i] = 0;
+ }
+ for (let i = 0; i < gLastSnapShot.length; ++i) {
+ gLastSnapShot[i] = null;
+ }
+}
+
+function checkIfFinished() {
+ if (gFinished) {
+ return;
+ }
+
+ for (var i = 0; i < gNumFrameUpdates.length; ++i) {
+ if (gNumFrameUpdates[i] < kNumFrameUpdatesToExpect ||
+ gNumSnapShotChanges[i] < kNumFrameUpdatesToExpect) {
+ return;
+ }
+ }
+
+ ok(true, "got expected frame updates");
+ gFinished = true;
+
+ if (gNumDiscards == 0) {
+ // If we haven't discarded any complete images, we should do so, and
+ // verify the animation again.
+ setTimeout(step5, 0);
+ return;
+ }
+
+ SimpleTest.finish();
+}
+
+// arrayIndex is the index into the arrays gNumFrameUpdates and gNumDecodes
+// to increment when a frame update notification is received.
+function addCallbacks(anImage, arrayIndex) {
+ var observer = new ImageDecoderObserverStub();
+ observer.discard = function () {
+ gNumDiscards++;
+ ok(true, "got image discard");
+ if (gNumDiscards == gImgs.length) {
+ step6();
+ }
+ };
+ observer.frameUpdate = function () {
+ if (!gCountingFrameUpdates) {
+ return;
+ }
+
+ // Do this off a setTimeout since nsImageLoadingContent uses a scriptblocker
+ // when it notifies us and calling drawWindow can call will paint observers
+ // which can dispatch a scrollport event, and events assert if dispatched
+ // when there is a scriptblocker.
+ setTimeout(function () {
+ gNumFrameUpdates[arrayIndex]++;
+
+ var r = document.getElementById(gImgs[arrayIndex]).getBoundingClientRect();
+ var snapshot = snapshotRect(window, r, "rgba(0,0,0,0)");
+ if (gLastSnapShot[arrayIndex] != null) {
+ if (snapshot.toDataURL() != gLastSnapShot[arrayIndex].toDataURL()) {
+ gNumSnapShotChanges[arrayIndex]++;
+ }
+ }
+ gLastSnapShot[arrayIndex] = snapshot;
+
+ if (gNumFrameUpdates[arrayIndex] >= kNumFrameUpdatesToExpect &&
+ gNumSnapShotChanges[arrayIndex] >= kNumFrameUpdatesToExpect &&
+ gNumDiscards >= gImgs.length) {
+ if (!gRemovedObserver[arrayIndex]) {
+ ok(true, "removing observer for " + arrayIndex);
+ gRemovedObserver[arrayIndex] = true;
+ imgLoadingContent.removeObserver(scriptedObserver);
+ }
+ }
+ if (!gFinished) {
+ // because we do this in a setTimeout we can have several in flight
+ // so don't call ok if we've already finished.
+ ok(true, "got frame update");
+ }
+ checkIfFinished();
+ }, 0);
+ };
+ observer = SpecialPowers.wrapCallbackObject(observer);
+
+ var scriptedObserver = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
+ .getService(SpecialPowers.Ci.imgITools)
+ .createScriptedObserver(observer);
+
+ var imgLoadingContent = SpecialPowers.wrap(anImage);
+ imgLoadingContent.addObserver(scriptedObserver);
+}
+
+function requestDiscard(anImage) {
+ var request = SpecialPowers.wrap(anImage)
+ .getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST);
+ setTimeout(() => request.requestDiscard(), 0);
+}
+
+function drawCanvas(anImage) {
+ var canvas = document.getElementById('canvas');
+ var context = canvas.getContext('2d');
+
+ context.clearRect(0,0,100,100);
+ var cleared = canvas.toDataURL();
+
+ context.drawImage(anImage, 0, 0);
+ ok(true, "we got through the drawImage call without an exception being thrown");
+
+ ok(cleared != canvas.toDataURL(), "drawImage drew something");
+}
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/image/test/mochitest/test_drawDiscardedImage.html b/image/test/mochitest/test_drawDiscardedImage.html
new file mode 100644
index 0000000000..f1a2dde89c
--- /dev/null
+++ b/image/test/mochitest/test_drawDiscardedImage.html
@@ -0,0 +1,85 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=731419
+-->
+<head>
+ <title>Test for Bug 731419 - Draw an ostensibly discarded image to a canvas</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<body>
+
+<!--
+ Load an image in an iframe, then draw that image to a canvas. Then set the
+ iframe to display:none (after bug 731419, this causes the image's decoded
+ data to be discarded) and draw the image to a canvas again. We should draw
+ the same image data both times.
+-->
+
+<script>
+
+SimpleTest.waitForExplicitFinish();
+
+var data1;
+
+function drawImage()
+{
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ var iframeDoc = document.getElementById('iframe').contentDocument;
+
+ ctx.clearRect(0, 0, canvas.height, canvas.width);
+ ctx.drawImage(iframeDoc.getElementById('image'), 0, 0);
+ return canvas.toDataURL();
+}
+
+function iframeLoad()
+{
+ data1 = drawImage();
+ document.getElementById('iframe').style.display = 'none';
+
+ // Spin the event loop a few times to give the image in the display:none
+ // iframe a chance to be discarded.
+ SimpleTest.executeSoon(function() {
+ SimpleTest.executeSoon(function() {
+ SimpleTest.executeSoon(function() {
+ step2();
+ });
+ });
+ });
+}
+
+function step2()
+{
+ is(drawImage(), data1, "Same image before and after iframe display:none");
+ SimpleTest.finish();
+}
+
+</script>
+
+<canvas id='canvas'></canvas>
+
+<iframe id='iframe' onload='iframeLoad()' srcdoc='<img id="image"
+src="data:image/png;base64,
+iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADRElEQVQ4EQXBTWgcZQCA4ff7ZmZ3
+NpvNZLObTWpCuoZGIxWJplAKbVUKavUiHrQHaRG1XrV4SNuD4MFcRDwUoR4qEq2gFUlBEWmtppYi
+acSmMakxtfkx/5tNdmd35/8bn0cAzJ7IXwKGH/q8NDF48vy+7vk/3tzVXDs8nj9cAAiDcD70gwVi
+vvvr4tsjAAAAAmD2RD4GOL34wge21XHsnHWh9/aUjX1pC4C1UpXrP08zN7vMvvujPx3P/PD+0VH3
+BoAcTspXAbK9iuGe78+csy70ZnsVvh+xWQ8p1QI8dNK7CiT9CmeO28/4ZsuVX9/IvQwgmzLaU9LS
+AGh/3KJ5jw6A6ynyL7Xx7UCORiwQGRN0g7C4m4FX9poNV35681ShU6ZbxKDRLJVuZQl9RdSQRB4c
+OtDGoQNtPGHBuh0SaAa+ZvLjHYt8fwfZrpTl2cFp2ZwVDyQzSgLgVIndGN/tIP/c61y/WWb14gaV
+asTWioPSDabnfCqVkK7BHKHtPK0n06oFGQHgewJtbw8AujGNkYTNpTJxbYfaygqR0piYkaRkhMya
+eI2oX9dTQRIFmtrmz7EGpS9vESZjAN7tfo/UL2PouoZwbfxIo9jaoLWlzI7jEPmhLjVEbXs5IPAE
+jx5M0Z5RZDJwqjCENFN8XBtmOP0FXq1O6NR5snsRtsv4C+voCdHQpcfVtTn/xUKXTrMlyfck6BCC
+a02fkDZDqirF5JVrRA8ewagu8NbADN6az9btMoTqjnasKDTHjp5PSM3I5DQy7UliZbCz7bCwFDD/
+b52h3BCviVHOHv2bvmydyvwOM5MSmch9Ji4/SxMNcaNJTw707zdJmBqeo+G5BuO/V6AzQ5Oo01MI
+KBaTOOis3rPZrKeqrbn2hwXA10fY7zvicqeZKPQ8YpKxJCgIpEQXisBVhG6MYcQ0pGJp2XWnSpx8
+52o0ogF8c5/ltMlGIlYHo0qQrq9HxHWFvx3RqCoCFzwn4L+tiIVV5Y5MhWc/mlDnATQAgMkynbMb
+opoN4z2hUAlPBdpO6FNp+JTtkPVaHE7NYX94K/xqrBT/BvwDIAAAgALQAfT1aWJwtyYea9VEXoAo
+RfHGYhTfvRfF48BdYB3YAPgfnOuE39kFlREAAAAASUVORK5CYII=">'></iframe>
+
+</body>
+</html>
+
diff --git a/image/test/mochitest/test_error_events.html b/image/test/mochitest/test_error_events.html
new file mode 100644
index 0000000000..89ed9da528
--- /dev/null
+++ b/image/test/mochitest/test_error_events.html
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=715308
+-->
+<head>
+ <title>Test for Bug 715308 comment 93</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+
+<!-- Test for Bug 715308 comment 93:
+
+ - For a valid image, onload is fired and onerror is never fired.
+ - For an image with errors, onerror is fired, but onload is never fired.
+ - For any image, either onload or onerror is fired, but never both.
+
+ -->
+<script type="text/javascript">
+"use strict";
+
+SimpleTest.waitForExplicitFinish();
+
+var numCallbacks = 0;
+
+function image_error(name)
+{
+ numCallbacks++;
+ ok(name == 'error-early', "Got onerror for " + name);
+}
+
+function image_load(name)
+{
+ numCallbacks++;
+ ok(name == 'shaver', "Got onload for " + name);
+}
+
+function page_load()
+{
+ ok(numCallbacks == 2, 'Got page load before all onload/onerror callbacks?');
+
+ // Spin the event loop a few times to let image_error run if it's going to,
+ // then finish the test.
+ SimpleTest.executeSoon(function() {
+ SimpleTest.executeSoon(function() {
+ SimpleTest.executeSoon(function() {
+ SimpleTest.finish();
+ });
+ });
+ });
+}
+
+addEventListener('load', page_load);
+
+</script>
+
+<div id="content">
+ <img src='shaver.png' onerror='image_error("shaver")' onload='image_load("shaver")'>
+ <img src='error-early.png' onerror='image_error("error-early")' onload='image_load("error-early")'>
+</div>
+
+</pre>
+</body>
+</html>
+
diff --git a/image/test/mochitest/test_has_transparency.html b/image/test/mochitest/test_has_transparency.html
new file mode 100644
index 0000000000..482aaf96b9
--- /dev/null
+++ b/image/test/mochitest/test_has_transparency.html
@@ -0,0 +1,169 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1089880
+-->
+<head>
+ <title>Test for Bug 1089880</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1089880">Mozilla Bug 1089880</a>
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 1089880 **/
+
+SimpleTest.requestFlakyTimeout("Early failure timeout");
+SimpleTest.waitForExplicitFinish();
+
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+const Cc = SpecialPowers.Cc;
+const Ci = SpecialPowers.Ci;
+const gContent = document.getElementById("content");
+
+var gCanvas;
+var gCanvasCtx;
+var gImg;
+var gMyDecoderObserver;
+var gIsTestFinished = false;
+var gFiles;
+var gCurrentFileIsTransparent = false;
+var gHasTransparencyWasCalled = false;
+
+function* testFiles() {
+ // [A, B] where 'A' is the image and 'B' is whether it's transparent.
+
+ // PNGs and GIFs may be transparent or not.
+ yield ["red.png", false];
+ yield ["transparent.png", true];
+ yield ["animated-gif-finalframe.gif", false];
+ yield ["transparent.gif", true];
+
+ // GIFs with padding on the first frame are always transparent.
+ yield ["first-frame-padding.gif", true];
+
+ // JPEGs are never transparent.
+ yield ["damon.jpg", false];
+
+ // Most BMPs are not transparent. (The TestMetadata GTest, which will
+ // eventually replace this test totally, has coverage for the kinds that can be
+ // transparent.)
+ yield ["opaque.bmp", false];
+
+ // ICO files which contain BMPs have an additional type of transparency - the
+ // AND mask - that warrants separate testing. (Although, after bug 1201796,
+ // all ICOs are considered transparent.)
+ yield ["ico-bmp-opaque.ico", true];
+ yield ["ico-bmp-transparent.ico", true];
+
+ // SVGs are always transparent.
+ yield ["lime100x100.svg", true];
+}
+
+function loadNext() {
+ var currentFile = "";
+ gHasTransparencyWasCalled = false;
+ let {done, value} = gFiles.next();
+ if (done) {
+ // We ran out of test files.
+ cleanUpAndFinish();
+ return;
+ }
+ [currentFile, gCurrentFileIsTransparent] = value;
+ gImg.setAttribute("src", currentFile);
+}
+
+function onHasTransparency(aRequest) {
+ gHasTransparencyWasCalled = true;
+}
+
+function onDecodeComplete(aRequest) {
+ if (!gCurrentFileIsTransparent) {
+ ok(!gHasTransparencyWasCalled,
+ "onHasTransparency was not called for non-transparent file " + gImg.src);
+ } else {
+ ok(gHasTransparencyWasCalled,
+ "onHasTransparency was called for transparent file " + gImg.src);
+ }
+ loadNext();
+}
+
+function onError() {
+ if (gIsTestFinished) {
+ return;
+ }
+ ok(false, "Should successfully load " + gImg.src);
+ loadNext();
+}
+
+function onLoad() {
+ if (gIsTestFinished) {
+ return;
+ }
+ ok(true, "Should successfully load " + gImg.src);
+
+ // Force decoding of the image.
+ SimpleTest.executeSoon(function() {
+ gCanvasCtx.drawImage(gImg, 0, 0);
+ });
+}
+
+function failTest() {
+ ok(false, "timing out after " + FAILURE_TIMEOUT + "ms. " +
+ "currently displaying " + gImg.src);
+ cleanUpAndFinish();
+}
+
+function cleanUpAndFinish() {
+ if (gIsTestFinished) {
+ return;
+ }
+ gIsTestFinished = true;
+ let imgLoadingContent = SpecialPowers.wrap(gImg);
+ imgLoadingContent.removeObserver(gMyDecoderObserver);
+ SimpleTest.finish();
+}
+
+function main() {
+ gFiles = testFiles();
+ gCanvas = document.createElement('canvas');
+ gCanvasCtx = gCanvas.getContext('2d');
+ gImg = new Image();
+ gImg.onload = onLoad;
+ gImg.onerror = onError;
+
+ // Create, customize & attach decoder observer.
+ var observer = new ImageDecoderObserverStub();
+ observer.hasTransparency = onHasTransparency;
+ observer.decodeComplete = onDecodeComplete;
+ gMyDecoderObserver =
+ Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
+ .createScriptedObserver(SpecialPowers.wrapCallbackObject(observer));
+ let imgLoadingContent = SpecialPowers.wrap(gImg);
+ imgLoadingContent.addObserver(gMyDecoderObserver);
+
+ // We want to test the cold loading behavior, so clear cache in case an
+ // earlier test got our image in there already.
+ clearAllImageCaches();
+
+ // Load the first image.
+ loadNext();
+
+ // In case something goes wrong, fail earlier than mochitest timeout,
+ // and with more information.
+ setTimeout(failTest, FAILURE_TIMEOUT);
+}
+
+window.onload = main;
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_image_cache_notification.html b/image/test/mochitest/test_image_cache_notification.html
new file mode 100644
index 0000000000..73adac25ff
--- /dev/null
+++ b/image/test/mochitest/test_image_cache_notification.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ </head>
+ <body>
+ <button>Add Image</button>
+ <script>
+ /* Test to ensure http-on-image-cache-response should only be notified
+ * once per image
+ */
+
+ SimpleTest.waitForExplicitFinish();
+ async function addImage() {
+ const newImage = document.createElement("img");
+
+ const imageLoaded = new Promise((r) => {
+ newImage.onload = r;
+ });
+
+ newImage.src = "./over.png";
+ document.body.appendChild(newImage);
+ return imageLoaded;
+ }
+
+ let imageCacheCallbackRunCount = 0;
+ const cb = SpecialPowers.wrapCallback(() => {
+ imageCacheCallbackRunCount += 1;
+ });
+ SpecialPowers.addObserver(cb, "http-on-image-cache-response");
+
+ async function runTest() {
+ await addImage();
+ SimpleTest.ok(imageCacheCallbackRunCount == 0, "first load of over.png shouldn't be cached");
+ await addImage();
+ SimpleTest.ok(imageCacheCallbackRunCount == 1, "second load of over.png should be cached");
+ await addImage();
+ await addImage();
+ await addImage();
+ SimpleTest.ok(imageCacheCallbackRunCount == 1, "further loads of over.png shouldn't be notified");
+ SimpleTest.finish();
+ }
+
+ runTest();
+ </script>
+ </body>
+</html>
diff --git a/image/test/mochitest/test_image_crossorigin_data_url.html b/image/test/mochitest/test_image_crossorigin_data_url.html
new file mode 100644
index 0000000000..4465b5aab4
--- /dev/null
+++ b/image/test/mochitest/test_image_crossorigin_data_url.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test for handling of 'crossorigin' attribute on CSS link with data: URL</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="someuniqueidhere"></div>
+<img id="testimg" crossorigin src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC">
+<script>
+ /* global async_test, assert_equals */
+ var t = async_test("img@crossorigin with data: src");
+ window.addEventListener("load", t.step_func_done(function() {
+ var img = document.getElementById("testimg");
+ assert_equals(img.naturalWidth, 1, "Should have 1px width");
+ assert_equals(img.naturalHeight, 1, "Should have 1px height");
+ var c = document.createElement("canvas");
+ c.width = c.height = 1;
+ var ctx = c.getContext("2d");
+ ctx.drawImage(img, 0, 0);
+ var data = ctx.getImageData(0, 0, 1, 1);
+ assert_equals(data.width, 1, "Should have 1px data width");
+ assert_equals(data.height, 1, "Should have 1px data height");
+ assert_equals(data.data[0], 255, "Should have lots of red");
+ assert_equals(data.data[1], 0, "Should have no green");
+ assert_equals(data.data[2], 0, "Should have no blue");
+ assert_equals(data.data[3], 255, "Should have no translucency");
+ }));
+</script>
diff --git a/image/test/mochitest/test_mq_dynamic_svg.html b/image/test/mochitest/test_mq_dynamic_svg.html
new file mode 100644
index 0000000000..25b708224e
--- /dev/null
+++ b/image/test/mochitest/test_mq_dynamic_svg.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Dynamic changes to prefers-color-scheme affecting SVG images</title>
+<link rel=stylesheet type=text/css href=/tests/SimpleTest/test.css>
+<script src=/tests/SimpleTest/SimpleTest.js></script>
+<script src=/tests/SimpleTest/WindowSnapshot.js></script>
+<body onload=run()>
+<iframe id=f1 width=300 height=600></iframe>
+<iframe id=f2 width=300 height=600></iframe>
+<script>
+SimpleTest.waitForExplicitFinish();
+
+// Not strictly needed, but keeps eslint happy.
+let f1 = window.f1;
+let f2 = window.f2;
+
+function snapshotsEqual() {
+ let s1 = snapshotWindow(f1.contentWindow);
+ let s2 = snapshotWindow(f2.contentWindow);
+ return compareSnapshots(s1, s2, true)[0];
+}
+
+function waitForColorSchemeToBe(scheme) {
+ return new Promise(resolve => {
+ let mq = matchMedia(`(prefers-color-scheme: ${scheme})`);
+ if (mq.matches) {
+ resolve();
+ } else {
+ mq.addEventListener("change", resolve, { once: true });
+ }
+ });
+}
+
+async function run() {
+ let loadedFrame1 = new Promise(resolve => f1.onload = resolve);
+ let loadedFrame2 = new Promise(resolve => f2.onload = resolve);
+ await SpecialPowers.pushPrefEnv({ set: [["layout.css.prefers-color-scheme.content-override", 1]] });
+ await waitForColorSchemeToBe("light");
+ f1.src = "mq_dynamic_svg_test.html";
+ f2.src = "mq_dynamic_svg_ref.html";
+ await loadedFrame1;
+ await loadedFrame2;
+ ok(!snapshotsEqual(), "In light mode snapshot comparison should be false");
+ await SpecialPowers.pushPrefEnv({ set: [["layout.css.prefers-color-scheme.content-override", 0]] });
+ await waitForColorSchemeToBe("dark");
+ ok(snapshotsEqual(), "In dark mode snapshot comparison should be true");
+ SimpleTest.finish();
+}
+</script>
diff --git a/image/test/mochitest/test_net_failedtoprocess.html b/image/test/mochitest/test_net_failedtoprocess.html
new file mode 100644
index 0000000000..470f3f5b31
--- /dev/null
+++ b/image/test/mochitest/test_net_failedtoprocess.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+Test that a image decoding error producs a net:failed-to-process-uri-content
+observer event with the nsIURI of the failed image as the subject
+-->
+<head>
+ <title>Test for image net:failed-to-process-uri-content</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+<pre id="test">
+</pre>
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+const Ci = SpecialPowers.Ci;
+const Cc = SpecialPowers.Cc;
+var obs = Cc["@mozilla.org/observer-service;1"].getService();
+obs = obs.QueryInterface(Ci.nsIObserverService);
+
+var observer = {
+ /* eslint-disable-next-line mozilla/use-chromeutils-generateqi */
+ QueryInterface (aIID) {
+ if (aIID.equals(Ci.nsISupports) ||
+ aIID.equals(Ci.nsIObserver))
+ return this;
+ throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
+ },
+
+ observe(subject, topic, data) {
+ ok(topic == "net:failed-to-process-uri-content", "wrong topic");
+ subject = subject.QueryInterface(Ci.nsIURI);
+ is(subject.asciiSpec, `${location.origin}/tests/image/test/mochitest/invalid.jpg`, "wrong subject");
+
+ obs.removeObserver(this, "net:failed-to-process-uri-content");
+
+ SimpleTest.finish();
+ }
+};
+
+obs.addObserver(SpecialPowers.wrapCallbackObject(observer), "net:failed-to-process-uri-content");
+
+document.write('<img src="damon.jpg">');
+document.write('<img src="invalid.jpg">');
+
+</script>
+</body>
+</html>
diff --git a/image/test/mochitest/test_removal_ondecode.html b/image/test/mochitest/test_removal_ondecode.html
new file mode 100644
index 0000000000..4ce7555757
--- /dev/null
+++ b/image/test/mochitest/test_removal_ondecode.html
@@ -0,0 +1,160 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=841579
+-->
+<head>
+ <title>Test for Bug 841579</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=841579">Mozilla Bug 841579</a>
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 841579**/
+
+SimpleTest.requestFlakyTimeout("Early failure timeout");
+SimpleTest.waitForExplicitFinish();
+
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+const Cc = SpecialPowers.Cc;
+const Ci = SpecialPowers.Ci;
+const gContent = document.getElementById("content");
+
+var gImg;
+var gMyDecoderObserver;
+var gIsTestFinished = false;
+var gFiles;
+var gNotifications = 0;
+var gLoads = 0;
+var gRemovals = 0;
+var gExpected = 5;
+
+function* fileToLoad() {
+ yield "red.png";
+ yield "invalid.jpg";
+ yield "lime100x100.svg";
+ yield "bad.jpg";
+ yield "rillybad.jpg";
+}
+
+function onSizeAvailable(aRequest) {
+ ok(true, "AfterLoad.onSizeAvailable called for " + gImg.src);
+}
+function onLoadComplete(aRequest) {
+ ok(gExpected > gLoads, "AfterLoad.onLoadComplete called for " + gImg.src);
+ gLoads++;
+
+ // We aren't going to get a decode complete event if the metadata decoding
+ // failed (i.e. for invalid.jpg). By definition we should have the size or
+ // an error once we get a load complete event, so check if the size is valid
+ // and if not, trigger a decode complete event manually.
+ var hasSize = false;
+ try {
+ hasSize = aRequest.image.width > 0 && aRequest.image.height > 0;
+ } catch(e) {}
+
+ if (hasSize) {
+ maybeAdvance();
+ } else {
+ onDecodeComplete(aRequest);
+ }
+}
+
+function onDecodeComplete(aRequest) {
+ ok(gExpected > gRemovals, "AfterLoad.onDecodeComplete called for " + gImg.src);
+ SimpleTest.executeSoon(function() {
+ try {
+ gContent.removeChild(gImg);
+ }
+ catch (e) {}
+ gRemovals++;
+ maybeAdvance();
+ });
+}
+
+function failTest() {
+ ok(false, "timing out after " + FAILURE_TIMEOUT + "ms. " +
+ "currently displaying " + gImg.src);
+ cleanUpAndFinish();
+}
+
+function onNotification()
+{
+ ok(gExpected > gNotifications, "AfterLoad.onNotification called for " + gImg.src);
+ gNotifications++;
+ maybeAdvance();
+}
+
+function maybeAdvance()
+{
+ if (gNotifications != gLoads || gNotifications != gRemovals) {
+ return;
+ }
+
+ let {done, value} = gFiles.next();
+ if (done) {
+ cleanUpAndFinish();
+ return;
+ }
+ gImg.src = value;
+ gContent.appendChild(gImg);
+}
+
+function cleanUpAndFinish() {
+ // On the off chance that failTest and myOnStopFrame are triggered
+ // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish.
+ if (gIsTestFinished) {
+ return;
+ }
+ let imgLoadingContent = SpecialPowers.wrap(gImg);
+ imgLoadingContent.removeObserver(gMyDecoderObserver);
+ // TODO - this isn't the case until post-bug 716140's refactorings
+ // ok(gNotifications == gLoads, "Should be notified the same number of times as loads");
+ SimpleTest.finish();
+ gIsTestFinished = true;
+}
+
+function main() {
+ gFiles = fileToLoad();
+ gImg = new Image();
+ gImg.onload = onNotification;
+ gImg.onerror = onNotification;
+
+ // Create, customize & attach decoder observer
+ var observer = new ImageDecoderObserverStub();
+ observer.sizeAvailable = onSizeAvailable;
+ observer.loadComplete = onLoadComplete;
+ observer.decodeComplete = onDecodeComplete;
+ gMyDecoderObserver =
+ Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
+ .createScriptedObserver(SpecialPowers.wrapCallbackObject(observer));
+ let imgLoadingContent = SpecialPowers.wrap(gImg);
+ imgLoadingContent.addObserver(gMyDecoderObserver);
+
+ // We want to test the cold loading behavior, so clear cache in case an
+ // earlier test got our image in there already.
+ clearAllImageCaches();
+
+ // kick off image-loading! myOnStopFrame handles the rest.
+ gImg.setAttribute("src", gFiles.next().value);
+ gContent.appendChild(gImg);
+
+ // In case something goes wrong, fail earlier than mochitest timeout,
+ // and with more information.
+ setTimeout(failTest, FAILURE_TIMEOUT);
+}
+
+window.onload = main;
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_removal_onload.html b/image/test/mochitest/test_removal_onload.html
new file mode 100644
index 0000000000..0a060542f5
--- /dev/null
+++ b/image/test/mochitest/test_removal_onload.html
@@ -0,0 +1,142 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=841579
+-->
+<head>
+ <title>Test for Bug 841579</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=841579">Mozilla Bug 841579</a>
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 841579**/
+
+SimpleTest.requestFlakyTimeout("Early failure timeout");
+SimpleTest.waitForExplicitFinish();
+
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+const Cc = SpecialPowers.Cc;
+const Ci = SpecialPowers.Ci;
+const gContent = document.getElementById("content");
+
+var gImg;
+var gMyDecoderObserver;
+var gIsTestFinished = false;
+var gFiles;
+var gNotifications = 0;
+var gLoads = 0;
+var gRemovals = 0;
+var gExpected = 5;
+
+function* fileToLoad() {
+ yield "red.png";
+ yield "invalid.jpg";
+ yield "lime100x100.svg";
+ yield "bad.jpg";
+ yield "rillybad.jpg";
+}
+
+function onSizeAvailable(aRequest) {
+ ok(true, "AfterLoad.onSizeAvailable called for " + gImg.src);
+}
+function onLoadComplete(aRequest) {
+ ok(gExpected > gLoads, "AfterLoad.onLoadComplete called for " + gImg.src);
+ gLoads++;
+ SimpleTest.executeSoon(function() {
+ try {
+ gContent.removeChild(gImg);
+ }
+ catch (e) {}
+ gRemovals++;
+ maybeAdvance();
+ });
+}
+function onDecodeComplete(aRequest) {
+ ok(true, "AfterLoad.onDecodeComplete called for " + gImg.src);
+}
+
+function failTest() {
+ ok(false, "timing out after " + FAILURE_TIMEOUT + "ms. " +
+ "currently displaying " + gImg.src);
+ cleanUpAndFinish();
+}
+
+function onNotification()
+{
+ gNotifications++;
+ maybeAdvance();
+}
+
+function maybeAdvance()
+{
+ if (gRemovals != gNotifications) {
+ return;
+ }
+
+ let {done, value} = gFiles.next();
+ if (done) {
+ cleanUpAndFinish();
+ return;
+ }
+ gImg.src = value;
+ gContent.appendChild(gImg);
+}
+
+function cleanUpAndFinish() {
+ // On the off chance that failTest and myOnStopFrame are triggered
+ // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish.
+ if (gIsTestFinished) {
+ return;
+ }
+ let imgLoadingContent = SpecialPowers.wrap(gImg);
+ imgLoadingContent.removeObserver(gMyDecoderObserver);
+ // TODO: this isn't the case until post-bug 716140's refactorings
+ // ok(gNotifications == gLoads, "Should be notified the same number of times as loads");
+ SimpleTest.finish();
+ gIsTestFinished = true;
+}
+
+function main() {
+ gFiles = fileToLoad();
+ gImg = new Image();
+ gImg.onload = onNotification;
+ gImg.onerror = onNotification;
+
+ // Create, customize & attach decoder observer
+ var observer = new ImageDecoderObserverStub();
+ observer.sizeAvailable = onSizeAvailable;
+ observer.loadComplete = onLoadComplete;
+ observer.decodeComplete = onDecodeComplete;
+ gMyDecoderObserver =
+ Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
+ .createScriptedObserver(SpecialPowers.wrapCallbackObject(observer));
+ let imgLoadingContent = SpecialPowers.wrap(gImg);
+ imgLoadingContent.addObserver(gMyDecoderObserver);
+
+ // We want to test the cold loading behavior, so clear cache in case an
+ // earlier test got our image in there already.
+ clearAllImageCaches();
+
+ // kick off image-loading! myOnStopFrame handles the rest.
+ gImg.setAttribute("src", gFiles.next());
+
+ // In case something goes wrong, fail earlier than mochitest timeout,
+ // and with more information.
+ setTimeout(failTest, FAILURE_TIMEOUT);
+}
+
+window.onload = main;
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_short_gif_header.html b/image/test/mochitest/test_short_gif_header.html
new file mode 100644
index 0000000000..f8294825b5
--- /dev/null
+++ b/image/test/mochitest/test_short_gif_header.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=844684
+-->
+<head>
+ <title>Test for Bug 844684</title>
+ <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=844684">Mozilla Bug 844684</a>
+<div id="content">
+<img id="testcontent" onload="success()" onerror="failure()">
+</div>
+<pre id="test">
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+document.getElementById('testcontent').src = "short_header.gif";
+
+function success() {
+ ok(true, "Image loaded.");
+ SimpleTest.finish();
+}
+
+function failure() {
+ ok(false, "Image didn't load.");
+ SimpleTest.finish();
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_staticClone.html b/image/test/mochitest/test_staticClone.html
new file mode 100644
index 0000000000..7400e064c6
--- /dev/null
+++ b/image/test/mochitest/test_staticClone.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=878037
+-->
+<head>
+ <title>Test for Bug 878037</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=878037">Mozilla Bug 878037</a>
+<p id="display"></p>
+<div>
+ <!-- transparent-animation.gif from the gif reftests. -->
+ <img id="animated" src="data:image/gif;base64,R0lGODlhZABkAIABAP8AAP///yH5BAkBAAEALAAAAABLAGQAAAK8jI+py+0Po5y02ouz3rz7D4biSJbmiabqyrbuC8fyTNf2jef6zvf+DwwKh8Si8YhMKpchgPMJjUqnVOipis1ir9qul+sNV8HistVkTj/JajG7/UXDy+95tm4fy/NdPF/q93dWIqgVWAhwWKgoyPjnyAeZJ2lHOWcJh9mmqcaZ5mkGSreHOCXqRloadRrGGkeoapoa6+TaN0tra4gbq3vHq+q7BVwqrMeEnKy8zNzs/AwdLT1NXW19jZ1tUgAAIfkECQEAAQAsAAAAADQAZAAAArCMj6nL7Q+jnLTai7PevPsPhuJIluaJpurKtu4Lx/JM1/aN5/rO9/7vAAiHxKLxiCRCkswmc+mMSqHSapJqzSof2u4Q67WCw1MuOTs+N9Pqq7kdZcON8vk2aF+/88g6358HaCc4Rwhn2IaopnjGSOYYBukl2UWpZYm2x0enuXnX4NnXGQqAKTYaalqlWoZH+snwWsQah+pJ64Sr5ypbCvQLHCw8TFxsfIycrLzM3PxQAAAh+QQJAQABACwAAAAAGwBkAAACUIyPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gTE8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvdrfYnH5LL5jE6r16sCADs=">
+</div>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 878037**/
+
+SimpleTest.waitForExplicitFinish();
+
+window.onload = function() {
+ var img = document.getElementById("animated");
+ var content = SpecialPowers.wrap(img);
+
+ var request = content.getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST);
+
+ var staticReq = request.getStaticRequest();
+ var clone = staticReq.clone(null);
+
+ ok(clone, "hooray, we didn't crash!");
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_svg_animatedGIF.html b/image/test/mochitest/test_svg_animatedGIF.html
new file mode 100644
index 0000000000..04077676b7
--- /dev/null
+++ b/image/test/mochitest/test_svg_animatedGIF.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=666446
+-->
+<head>
+ <title>Test for Bug 666446 - Animated Raster Images inside of SVG Frames</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <script type="application/javascript" src="animationPolling.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+
+<!-- Make sure embed element is snapped to an exact pixel. -->
+<div class="bug-header" style="height: 100px;">
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
+ Mozilla Bug 666446: lots of animated gifs swamp us with paint events
+ </a>
+</div>
+
+<p id="display"></p>
+<div id="content">
+ <div id="referenceDiv" style="height: 40px; width: 40px;
+ display: none; background: #2aff00"></div>
+ <!--
+ We use <embed> here instead of <img> because the <img> tag utilizes
+ the VectorImage class for SVG, whereas in this test, we are testing
+ RasterImage.
+ -->
+ <embed id="embeddedSVG" src="animation.svg" type="image/svg+xml"
+ style="height: 40px; width: 40px; display: none;"/>
+</div>
+<div id="debug" style="display:none"></div>
+<pre id="test">
+<script type="text/javascript">
+
+/** Test for Bug 666446 SVGImageFrame/RasterImage**/
+
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+function main() {
+ var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
+ 'embeddedSVG', 'debug', '');
+ animTest.beginTest();
+}
+
+window.onload = main;
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_svg_filter_animation.html b/image/test/mochitest/test_svg_filter_animation.html
new file mode 100644
index 0000000000..b72aaa68c1
--- /dev/null
+++ b/image/test/mochitest/test_svg_filter_animation.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=666446
+-->
+<head>
+ <title>Test for Bug 666446 - Animated Images within SVG Filters</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <script type="application/javascript" src="animationPolling.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
+Mozilla Bug 666446: lots of animated gifs swamp us with paint events
+</a>
+<p id="display"></p>
+<div id="content">
+ <embed id="referenceImage" src="filter-final.svg" type="image/svg+xml" style="display: none;"/>
+ <embed id="embeddedSVGFilt" src="filter.svg" type="image/svg+xml" style="display: none;"/>
+</div>
+<div id="debug" style="display:none"></div>
+<pre id="test">
+<script type="text/javascript">
+
+/** Test for Bug 666446 nsSVGFEImageElement/RasterImage**/
+
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+function main() {
+ var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceImage',
+ 'embeddedSVGFilt', 'debug', '');
+ animTest.beginTest();
+}
+
+window.onload = main;
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_synchronized_animation.html b/image/test/mochitest/test_synchronized_animation.html
new file mode 100644
index 0000000000..3c2a874be1
--- /dev/null
+++ b/image/test/mochitest/test_synchronized_animation.html
@@ -0,0 +1,128 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=867758
+-->
+<head>
+ <title>Test for Bug 867758</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=867758">Mozilla Bug 867758</a>
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 867758**/
+
+SimpleTest.requestFlakyTimeout("Early failure timeout");
+SimpleTest.waitForExplicitFinish();
+
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+const Cc = SpecialPowers.Cc;
+const Ci = SpecialPowers.Ci;
+const gContent = document.getElementById("content");
+
+var gDispatched = false;
+var gRanEvent = false;
+var gObserver;
+var gImg1;
+var gImg2;
+var gFirstImageLoaded = false;
+var gOuter;
+var gFinished = false;
+var gFirstRequest = null;
+
+function cleanUpAndFinish() {
+ if (gFinished) {
+ return;
+ }
+ var imgLoadingContent = SpecialPowers.wrap(gImg1);
+ imgLoadingContent.removeObserver(gOuter);
+
+ imgLoadingContent = SpecialPowers.wrap(gImg2);
+ imgLoadingContent.removeObserver(gOuter);
+
+ SimpleTest.finish();
+
+ gFinished = true;
+}
+
+function frameUpdate(aRequest) {
+ if (!gDispatched) {
+ Promise.resolve().then(function() {
+ gRanEvent = true;
+ });
+ gDispatched = true;
+ gFirstRequest = aRequest;
+ } else if (aRequest != gFirstRequest) {
+ ok(!gRanEvent, "Should not have run event before all frame update events occurred!");
+ cleanUpAndFinish();
+ }
+}
+
+function failTest() {
+ ok(false, "timing out after " + FAILURE_TIMEOUT + "ms. ");
+ cleanUpAndFinish();
+}
+
+function waitForLoadAndTest(image) {
+ return () => {
+ // Draw the image into a canvas to ensure it's decoded.
+ var canvas = document.createElement('canvas');
+ var context = canvas.getContext('2d');
+ context.drawImage(image, 0, 0);
+
+ // Attach the observer.
+ var imgLoadingContent = SpecialPowers.wrap(image);
+ imgLoadingContent.addObserver(gOuter);
+
+ // If the other image already loaded, add both images to the document, which
+ // begins the real test.
+ if (gFirstImageLoaded) {
+ gContent.appendChild(gImg1);
+ gContent.appendChild(gImg2);
+ } else {
+ gFirstImageLoaded = true;
+ }
+ };
+}
+
+function main() {
+ gImg1 = new Image();
+ gImg2 = new Image();
+
+ // Create and customize decoder observer
+ var obs = new ImageDecoderObserverStub();
+ obs.frameUpdate = frameUpdate;
+
+ gOuter = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools).createScriptedObserver(SpecialPowers.wrapCallbackObject(obs));
+
+ // We want to test the cold loading behavior, so clear cache in case an
+ // earlier test got our image in there already.
+ clearAllImageCaches();
+
+ // These are two copies of the same image; hence, they have the same frame rate.
+ gImg1.src = "animated1.gif";
+ gImg2.src = "animated2.gif";
+
+ // Wait for each image to load.
+ gImg1.addEventListener('load', waitForLoadAndTest(gImg1));
+ gImg2.addEventListener('load', waitForLoadAndTest(gImg2));
+
+ // In case something goes wrong, fail earlier than mochitest timeout,
+ // and with more information.
+ setTimeout(failTest, FAILURE_TIMEOUT);
+}
+
+window.onload = main;
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_undisplayed_iframe.html b/image/test/mochitest/test_undisplayed_iframe.html
new file mode 100644
index 0000000000..695e4e5448
--- /dev/null
+++ b/image/test/mochitest/test_undisplayed_iframe.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=666446
+-->
+<head>
+<title>Test for Bug 666446 - Test for Animated Gif within IFRAME</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+<script type="application/javascript" src="imgutils.js"></script>
+<script type="application/javascript" src="animationPolling.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
+ Mozilla Bug 666446: lots of animated gifs swamp us with paint events</a>
+ <p id="display"></p>
+
+ <div id="content">
+ <div id="referenceDiv" style="display:none;">
+ <iframe id="referenceIFrame" src="ref-iframe.html" width="50%" height="100">
+ Browser does not support iframes.
+ </iframe>
+ </div>
+ <div id="animatedImage">
+ <iframe id="imageIFrame" src="iframe.html" width="50%" height="100" style="display: none;">
+ Browser does not support iframes.
+ </iframe>
+ </div>
+ <div id="debug" style="display: none"></div>
+ </div>
+ <pre id="test">
+<script type="text/javascript">
+const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
+
+function main()
+{
+ var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
+ 'imageIFrame', 'debug');
+ animTest.beginTest();
+}
+
+window.onload = main;
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_webcam.html b/image/test/mochitest/test_webcam.html
new file mode 100644
index 0000000000..8d6bf6b490
--- /dev/null
+++ b/image/test/mochitest/test_webcam.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=641748
+
+webcam-simulacrum.mgif is a hand-edited file containing red.gif and blue.gif,
+concatenated together with the relevant headers for
+multipart/x-mixed-replace. Specifically, with the headers in
+webcam-simulacrum.mjpg^headers^, the web browser will get the following:
+
+HTTP 200 OK
+Content-Type: multipart/x-mixed-replace;boundary=BOUNDARYOMG
+
+\-\-BOUNDARYOMG\r\n
+Content-Type: image/gif\r\n
+\r\n
+<contents of red.gif> (no newline)
+\-\-BOUNDARYOMG\r\n
+Content-Type: image/gif\r\n
+\r\n
+<contents of blue.gif> (no newline)
+\-\-BOUNDARYOMG\-\-\r\n
+
+(The boundary is arbitrary, and just has to be defined as something that
+won't be in the text of the contents themselves. \-\-$(boundary)\r\n means
+"Here is the beginning of a boundary," and \-\-$(boundary)\-\- means "All done
+sending you parts.")
+-->
+<head>
+ <title>Test for Bug 641748 - WebCam Simulacrum</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <script type="application/javascript" src="animationPolling.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=641748">
+Mozilla Bug 641748: GIF decoder doesn't support multipart/x-mixed-replace
+</a>
+<p id="display"></p>
+
+<div id="content">
+ <div id="referenceDiv" style="height: 100px; width: 100px;
+ display: none; background: #0018ff;"></div>
+ <div id="animatedImage">
+ <img id="animatedGif" src="webcam-simulacrum.sjs" style="display: none; height: 100px; width: 100px;">
+ <div id="text-descr"></div>
+ </div>
+ <div id="debug" style="display:none">
+ </div>
+</div>
+<pre id="test">
+<script type="text/javascript">
+const FAILURE_TIMEOUT = 60000; // Fail early after 60 seconds
+
+function main()
+{
+ var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
+ 'animatedGif', 'debug');
+ animTest.beginTest();
+}
+
+window.onload = main;
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/test_xultree_animation.xhtml b/image/test/mochitest/test_xultree_animation.xhtml
new file mode 100644
index 0000000000..801117ed37
--- /dev/null
+++ b/image/test/mochitest/test_xultree_animation.xhtml
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML>
+<html
+xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xml:lang="en" lang="en">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=666446
+-->
+<head>
+ <title>Test for Bug 666446 - Animated Images within SVG Filters</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <script type="application/javascript" src="imgutils.js"></script>
+ <script type="application/javascript" src="animationPolling.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446">
+Mozilla Bug 666446: lots of animated gifs swamp us with paint events
+</a>
+<p id="display"></p>
+<div id="content">
+ <xul:caption label="Bug 666446 - XULTree Test" />
+ <xul:separator />
+ <br />
+ <xul:window id="main" title="Bug 666446: XUL Tree Testing" style="width: 100px; height: 100px">
+ <xul:tree flex="1">
+ <xul:treecols>
+ <xul:treecol id="icon" label="Icon" flex="1" />
+ </xul:treecols>
+
+ <xul:treechildren>
+ <xul:treeitem id="referenceItem" hidden="true">
+ <xul:treerow>
+ <xul:treecell src="animated-gif-finalframe.gif" style="width: 40px; height: 40px;" />
+ </xul:treerow>
+ </xul:treeitem>
+ <xul:treeitem id="imageItem" hidden="true">
+ <xul:treerow>
+ <xul:treecell src="animated-gif.gif" style="width: 40px; height: 40px;" />
+ </xul:treerow>
+ </xul:treeitem>
+ </xul:treechildren>
+ </xul:tree>
+ </xul:window>
+ </div>
+<div id="debug" style="display:none"></div>
+<pre id="test">
+<script type="text/javascript">
+
+/** Test for Bug 666446 nsSVGFEImageElement/RasterImage**/
+
+const FAILURE_TIMEOUT = 5000; // Fail early after 120 seconds (2 minutes)
+
+function main() {
+ var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceItem',
+ 'imageItem', 'debug', '',
+ 'animated-gif-finalframe.gif', true);
+ animTest.beginTest();
+}
+
+window.onload = main;
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/image/test/mochitest/transparent.gif b/image/test/mochitest/transparent.gif
new file mode 100644
index 0000000000..48f5c7caf1
--- /dev/null
+++ b/image/test/mochitest/transparent.gif
Binary files differ
diff --git a/image/test/mochitest/transparent.png b/image/test/mochitest/transparent.png
new file mode 100644
index 0000000000..fc8002053a
--- /dev/null
+++ b/image/test/mochitest/transparent.png
Binary files differ
diff --git a/image/test/mochitest/webcam-simulacrum.sjs b/image/test/mochitest/webcam-simulacrum.sjs
new file mode 100644
index 0000000000..6243329eac
--- /dev/null
+++ b/image/test/mochitest/webcam-simulacrum.sjs
@@ -0,0 +1,51 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var counter = 2;
+var frames = ["red.gif", "blue.gif"];
+var timer = Cc["@mozilla.org/timer;1"];
+var partTimer = timer.createInstance(Ci.nsITimer);
+
+function getFileAsInputStream(aFilename) {
+ var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
+
+ file.append("tests");
+ file.append("image");
+ file.append("test");
+ file.append("mochitest");
+ file.append(aFilename);
+
+ var fileStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ fileStream.init(file, 1, 0, false);
+ return fileStream;
+}
+
+function handleRequest(request, response) {
+ response.setHeader(
+ "Content-Type",
+ "multipart/x-mixed-replace;boundary=BOUNDARYOMG",
+ false
+ );
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setStatusLine(request.httpVersion, 200, "OK");
+ response.processAsync();
+ response.write("--BOUNDARYOMG\r\n");
+ while (frames.length) {
+ sendNextPart(response);
+ }
+ response.write("--BOUNDARYOMG--\r\n");
+ response.finish();
+}
+
+function sendNextPart(response) {
+ var nextPartHead = "Content-Type: image/gif\r\n\r\n";
+ var inputStream = getFileAsInputStream(frames.shift());
+ response.bodyOutputStream.write(nextPartHead, nextPartHead.length);
+ response.bodyOutputStream.writeFrom(inputStream, inputStream.available());
+ inputStream.close();
+ // Toss in the boundary, so the browser can know this part is complete
+ response.write("--BOUNDARYOMG\r\n");
+}
diff --git a/image/test/reftest/ImageDocument.css b/image/test/reftest/ImageDocument.css
new file mode 100644
index 0000000000..b449810986
--- /dev/null
+++ b/image/test/reftest/ImageDocument.css
@@ -0,0 +1,16 @@
+body {
+ background-image: url("chrome://global/skin/media/imagedoc-darknoise.png");
+ margin: 0;
+}
+
+body > :first-child {
+ display: block;
+ position: absolute;
+ margin: auto;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background: hsl(0,0%,90%) url("chrome://global/skin/media/imagedoc-lightnoise.png");
+ color: #222;
+}
diff --git a/image/test/reftest/apng/bug411852-1-ref.html b/image/test/reftest/apng/bug411852-1-ref.html
new file mode 100644
index 0000000000..ce346c87ca
--- /dev/null
+++ b/image/test/reftest/apng/bug411852-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<img src="bug411852-1-ref.png">
+</body>
+</html>
diff --git a/image/test/reftest/apng/bug411852-1-ref.png b/image/test/reftest/apng/bug411852-1-ref.png
new file mode 100644
index 0000000000..04b862a1d9
--- /dev/null
+++ b/image/test/reftest/apng/bug411852-1-ref.png
Binary files differ
diff --git a/image/test/reftest/apng/bug411852-1.png b/image/test/reftest/apng/bug411852-1.png
new file mode 100644
index 0000000000..643f87e176
--- /dev/null
+++ b/image/test/reftest/apng/bug411852-1.png
Binary files differ
diff --git a/image/test/reftest/apng/bug546272-ref.html b/image/test/reftest/apng/bug546272-ref.html
new file mode 100644
index 0000000000..43afef15e1
--- /dev/null
+++ b/image/test/reftest/apng/bug546272-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<img src="bug546272-ref.png">
+</body>
+</html>
diff --git a/image/test/reftest/apng/bug546272-ref.png b/image/test/reftest/apng/bug546272-ref.png
new file mode 100644
index 0000000000..85dfd8ccfd
--- /dev/null
+++ b/image/test/reftest/apng/bug546272-ref.png
Binary files differ
diff --git a/image/test/reftest/apng/bug546272.png b/image/test/reftest/apng/bug546272.png
new file mode 100644
index 0000000000..5232d7f8f2
--- /dev/null
+++ b/image/test/reftest/apng/bug546272.png
Binary files differ
diff --git a/image/test/reftest/apng/delaytest.html b/image/test/reftest/apng/delaytest.html
new file mode 100644
index 0000000000..ee79254a2b
--- /dev/null
+++ b/image/test/reftest/apng/delaytest.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Delayed image reftest wrapper</title>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img id="image1" alt=" ">
+<script>
+
+window.addEventListener("MozReftestInvalidate", reftestInvalidateListener);
+
+// This loads a externally specified image, forces a draw (in case of
+// decode-on-draw), waits 100ms, and then triggers the reftest snapshot.
+// This allows the animation on the page to complete.
+//
+// Use as "delaytest.html?animation.png"
+//
+
+// Get the image URL from our URL
+var imgURL = document.location.search.substr(1);
+
+// Load the image
+var img = document.images[0];
+img.src = imgURL;
+img.onload = forceDecode;
+
+let decodeComplete = false;
+let gotReftestInvalidate = false;
+
+function forceDecode() {
+ img.decode().then(function() {
+ decodeComplete = true;
+ maybeStartTimer();
+ }, function() {
+ decodeComplete = true;
+ maybeStartTimer();
+ });
+}
+
+function reftestInvalidateListener() {
+ gotReftestInvalidate = true;
+ maybeStartTimer();
+}
+
+function maybeStartTimer() {
+ if (decodeComplete && gotReftestInvalidate) {
+ startTimer();
+ }
+}
+
+function startTimer() {
+ const delay = 100;
+ setTimeout("document.documentElement.className = '';", delay);
+}
+</script>
+</body>
+</html>
diff --git a/image/test/reftest/apng/reftest.list b/image/test/reftest/apng/reftest.list
new file mode 100644
index 0000000000..7ff6e561fe
--- /dev/null
+++ b/image/test/reftest/apng/reftest.list
@@ -0,0 +1,6 @@
+# APNG tests
+#
+# delaytest.html delays the reftest snapshot to allow time for the
+# animation to complete.
+== delaytest.html?bug411852-1.png bug411852-1-ref.html
+== delaytest.html?bug546272.png bug546272-ref.html
diff --git a/image/test/reftest/avif/1-normal.avif b/image/test/reftest/avif/1-normal.avif
new file mode 100644
index 0000000000..5cc9b295da
--- /dev/null
+++ b/image/test/reftest/avif/1-normal.avif
Binary files differ
diff --git a/image/test/reftest/avif/2-flipped-horizontally.avif b/image/test/reftest/avif/2-flipped-horizontally.avif
new file mode 100644
index 0000000000..f79492f776
--- /dev/null
+++ b/image/test/reftest/avif/2-flipped-horizontally.avif
Binary files differ
diff --git a/image/test/reftest/avif/3-rotated-180deg.avif b/image/test/reftest/avif/3-rotated-180deg.avif
new file mode 100644
index 0000000000..ba8f4565fe
--- /dev/null
+++ b/image/test/reftest/avif/3-rotated-180deg.avif
Binary files differ
diff --git a/image/test/reftest/avif/4-flipped-vertically.avif b/image/test/reftest/avif/4-flipped-vertically.avif
new file mode 100644
index 0000000000..77c2e651b8
--- /dev/null
+++ b/image/test/reftest/avif/4-flipped-vertically.avif
Binary files differ
diff --git a/image/test/reftest/avif/5-rotated-90deg-CCW-and-flipped-vertically.avif b/image/test/reftest/avif/5-rotated-90deg-CCW-and-flipped-vertically.avif
new file mode 100644
index 0000000000..4bfa631159
--- /dev/null
+++ b/image/test/reftest/avif/5-rotated-90deg-CCW-and-flipped-vertically.avif
Binary files differ
diff --git a/image/test/reftest/avif/6-rotated-90deg-CCW.avif b/image/test/reftest/avif/6-rotated-90deg-CCW.avif
new file mode 100644
index 0000000000..558356532e
--- /dev/null
+++ b/image/test/reftest/avif/6-rotated-90deg-CCW.avif
Binary files differ
diff --git a/image/test/reftest/avif/7-rotated-90deg-CW-and-flipped-vertically.avif b/image/test/reftest/avif/7-rotated-90deg-CW-and-flipped-vertically.avif
new file mode 100644
index 0000000000..08495f620b
--- /dev/null
+++ b/image/test/reftest/avif/7-rotated-90deg-CW-and-flipped-vertically.avif
Binary files differ
diff --git a/image/test/reftest/avif/8-rotated-90deg-CW.avif b/image/test/reftest/avif/8-rotated-90deg-CW.avif
new file mode 100644
index 0000000000..112bdac39e
--- /dev/null
+++ b/image/test/reftest/avif/8-rotated-90deg-CW.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irot0_imir0.avif b/image/test/reftest/avif/img_irot0_imir0.avif
new file mode 100644
index 0000000000..95ddcf0003
--- /dev/null
+++ b/image/test/reftest/avif/img_irot0_imir0.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irot0_imir1.avif b/image/test/reftest/avif/img_irot0_imir1.avif
new file mode 100644
index 0000000000..7006cbd98a
--- /dev/null
+++ b/image/test/reftest/avif/img_irot0_imir1.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irot0_imirN.avif b/image/test/reftest/avif/img_irot0_imirN.avif
new file mode 100644
index 0000000000..1455f67cd8
--- /dev/null
+++ b/image/test/reftest/avif/img_irot0_imirN.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irot1_imir0.avif b/image/test/reftest/avif/img_irot1_imir0.avif
new file mode 100644
index 0000000000..4069846f72
--- /dev/null
+++ b/image/test/reftest/avif/img_irot1_imir0.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irot1_imir1.avif b/image/test/reftest/avif/img_irot1_imir1.avif
new file mode 100644
index 0000000000..60f8b63739
--- /dev/null
+++ b/image/test/reftest/avif/img_irot1_imir1.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irot1_imirN.avif b/image/test/reftest/avif/img_irot1_imirN.avif
new file mode 100644
index 0000000000..141e46c5ae
--- /dev/null
+++ b/image/test/reftest/avif/img_irot1_imirN.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irot2_imir0.avif b/image/test/reftest/avif/img_irot2_imir0.avif
new file mode 100644
index 0000000000..d241c6f3c0
--- /dev/null
+++ b/image/test/reftest/avif/img_irot2_imir0.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irot2_imir1.avif b/image/test/reftest/avif/img_irot2_imir1.avif
new file mode 100644
index 0000000000..4af2f57522
--- /dev/null
+++ b/image/test/reftest/avif/img_irot2_imir1.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irot2_imirN.avif b/image/test/reftest/avif/img_irot2_imirN.avif
new file mode 100644
index 0000000000..fc3595b672
--- /dev/null
+++ b/image/test/reftest/avif/img_irot2_imirN.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irot3_imir0.avif b/image/test/reftest/avif/img_irot3_imir0.avif
new file mode 100644
index 0000000000..f8c7c6b7a1
--- /dev/null
+++ b/image/test/reftest/avif/img_irot3_imir0.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irot3_imir1.avif b/image/test/reftest/avif/img_irot3_imir1.avif
new file mode 100644
index 0000000000..971587853b
--- /dev/null
+++ b/image/test/reftest/avif/img_irot3_imir1.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irot3_imirN.avif b/image/test/reftest/avif/img_irot3_imirN.avif
new file mode 100644
index 0000000000..8235a2b0c2
--- /dev/null
+++ b/image/test/reftest/avif/img_irot3_imirN.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irotN_imir0.avif b/image/test/reftest/avif/img_irotN_imir0.avif
new file mode 100644
index 0000000000..163690ff71
--- /dev/null
+++ b/image/test/reftest/avif/img_irotN_imir0.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irotN_imir1.avif b/image/test/reftest/avif/img_irotN_imir1.avif
new file mode 100644
index 0000000000..9642b22411
--- /dev/null
+++ b/image/test/reftest/avif/img_irotN_imir1.avif
Binary files differ
diff --git a/image/test/reftest/avif/img_irotN_imirN.avif b/image/test/reftest/avif/img_irotN_imirN.avif
new file mode 100644
index 0000000000..5cc9b295da
--- /dev/null
+++ b/image/test/reftest/avif/img_irotN_imirN.avif
Binary files differ
diff --git a/image/test/reftest/avif/reftest.list b/image/test/reftest/avif/reftest.list
new file mode 100644
index 0000000000..10dc2f2d82
--- /dev/null
+++ b/image/test/reftest/avif/reftest.list
@@ -0,0 +1,17 @@
+defaults pref(image.avif.enabled,true) pref(image.avif.apply_transforms,true)
+
+== img_irot0_imir1.avif 2-flipped-horizontally.avif
+== img_irot0_imir0.avif 4-flipped-vertically.avif
+== img_irot0_imirN.avif 1-normal.avif
+== img_irot1_imir1.avif 7-rotated-90deg-CW-and-flipped-vertically.avif
+== img_irot1_imir0.avif 5-rotated-90deg-CCW-and-flipped-vertically.avif
+== img_irot1_imirN.avif 6-rotated-90deg-CCW.avif
+== img_irot2_imir1.avif 4-flipped-vertically.avif
+== img_irot2_imir0.avif 2-flipped-horizontally.avif
+== img_irot2_imirN.avif 3-rotated-180deg.avif
+== img_irot3_imir1.avif 5-rotated-90deg-CCW-and-flipped-vertically.avif
+== img_irot3_imir0.avif 7-rotated-90deg-CW-and-flipped-vertically.avif
+== img_irot3_imirN.avif 8-rotated-90deg-CW.avif
+== img_irotN_imir1.avif 2-flipped-horizontally.avif
+== img_irotN_imir0.avif 4-flipped-vertically.avif
+== img_irotN_imirN.avif 1-normal.avif
diff --git a/image/test/reftest/bmp/1240629-1.bmp b/image/test/reftest/bmp/1240629-1.bmp
new file mode 100644
index 0000000000..604d248e74
--- /dev/null
+++ b/image/test/reftest/bmp/1240629-1.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/1240629-2.bmp b/image/test/reftest/bmp/1240629-2.bmp
new file mode 100644
index 0000000000..e4fe80d595
--- /dev/null
+++ b/image/test/reftest/bmp/1240629-2.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-not-square-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-not-square-1bpp.bmp
new file mode 100644
index 0000000000..302e0c7120
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-not-square-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-not-square-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-not-square-1bpp.png
new file mode 100644
index 0000000000..f9318693db
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-not-square-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-15x15-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-15x15-1bpp.bmp
new file mode 100644
index 0000000000..e769ff864c
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-15x15-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-15x15-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-15x15-1bpp.png
new file mode 100644
index 0000000000..956c78ece6
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-15x15-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-16x16-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-16x16-1bpp.bmp
new file mode 100644
index 0000000000..ff012d98c5
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-16x16-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-16x16-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-16x16-1bpp.png
new file mode 100644
index 0000000000..90088351fa
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-16x16-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-17x17-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-17x17-1bpp.bmp
new file mode 100644
index 0000000000..86f56476e9
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-17x17-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-17x17-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-17x17-1bpp.png
new file mode 100644
index 0000000000..9a294696c4
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-17x17-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-1x1-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-1x1-1bpp.bmp
new file mode 100644
index 0000000000..0f98654d84
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-1x1-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-1x1-1bpp.ico b/image/test/reftest/bmp/bmp-1bpp/bmp-size-1x1-1bpp.ico
new file mode 100644
index 0000000000..5af8bef61a
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-1x1-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-1x1-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-1x1-1bpp.png
new file mode 100644
index 0000000000..7a07a124ea
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-1x1-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-2x2-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-2x2-1bpp.bmp
new file mode 100644
index 0000000000..5544c6437a
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-2x2-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-2x2-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-2x2-1bpp.png
new file mode 100644
index 0000000000..3b09f80769
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-2x2-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-31x31-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-31x31-1bpp.bmp
new file mode 100644
index 0000000000..8afcc56cc4
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-31x31-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-31x31-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-31x31-1bpp.png
new file mode 100644
index 0000000000..d1fe6ddeee
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-31x31-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-32x32-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-32x32-1bpp.bmp
new file mode 100644
index 0000000000..255e5526c7
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-32x32-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-32x32-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-32x32-1bpp.png
new file mode 100644
index 0000000000..078d3dc5d0
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-32x32-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-33x33-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-33x33-1bpp.bmp
new file mode 100644
index 0000000000..6d752a2e1d
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-33x33-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-33x33-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-33x33-1bpp.png
new file mode 100644
index 0000000000..e64e12b2aa
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-33x33-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-3x3-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-3x3-1bpp.bmp
new file mode 100644
index 0000000000..d4f885687d
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-3x3-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-3x3-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-3x3-1bpp.png
new file mode 100644
index 0000000000..b8519a8749
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-3x3-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-4x4-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-4x4-1bpp.bmp
new file mode 100644
index 0000000000..c0b9128feb
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-4x4-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-4x4-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-4x4-1bpp.png
new file mode 100644
index 0000000000..3977b54548
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-4x4-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-5x5-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-5x5-1bpp.bmp
new file mode 100644
index 0000000000..c02b2288d7
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-5x5-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-5x5-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-5x5-1bpp.png
new file mode 100644
index 0000000000..caa9246b67
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-5x5-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-6x6-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-6x6-1bpp.bmp
new file mode 100644
index 0000000000..64415c6ecb
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-6x6-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-6x6-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-6x6-1bpp.png
new file mode 100644
index 0000000000..30e1b0249d
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-6x6-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-7x7-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-7x7-1bpp.bmp
new file mode 100644
index 0000000000..d8e867a0d8
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-7x7-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-7x7-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-7x7-1bpp.png
new file mode 100644
index 0000000000..9dbaae84cb
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-7x7-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-8x8-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-8x8-1bpp.bmp
new file mode 100644
index 0000000000..207e84f80e
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-8x8-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-8x8-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-8x8-1bpp.png
new file mode 100644
index 0000000000..2201388408
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-8x8-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-9x9-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/bmp-size-9x9-1bpp.bmp
new file mode 100644
index 0000000000..871eb7c0f3
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-9x9-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/bmp-size-9x9-1bpp.png b/image/test/reftest/bmp/bmp-1bpp/bmp-size-9x9-1bpp.png
new file mode 100644
index 0000000000..7fe1b548b8
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/bmp-size-9x9-1bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/os2bmp-size-32x32-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/os2bmp-size-32x32-1bpp.bmp
new file mode 100644
index 0000000000..32bfc5e8f9
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/os2bmp-size-32x32-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-1bpp/reftest.list b/image/test/reftest/bmp/bmp-1bpp/reftest.list
new file mode 100644
index 0000000000..15274c2bc8
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/reftest.list
@@ -0,0 +1,21 @@
+# BMP 1BPP tests
+
+# Images of various sizes
+== bmp-size-1x1-1bpp.bmp bmp-size-1x1-1bpp.png
+== bmp-size-2x2-1bpp.bmp bmp-size-2x2-1bpp.png
+== bmp-size-3x3-1bpp.bmp bmp-size-3x3-1bpp.png
+== bmp-size-4x4-1bpp.bmp bmp-size-4x4-1bpp.png
+== bmp-size-5x5-1bpp.bmp bmp-size-5x5-1bpp.png
+== bmp-size-6x6-1bpp.bmp bmp-size-6x6-1bpp.png
+== bmp-size-7x7-1bpp.bmp bmp-size-7x7-1bpp.png
+== bmp-size-8x8-1bpp.bmp bmp-size-8x8-1bpp.png
+== bmp-size-9x9-1bpp.bmp bmp-size-9x9-1bpp.png
+== bmp-size-15x15-1bpp.bmp bmp-size-15x15-1bpp.png
+== bmp-size-16x16-1bpp.bmp bmp-size-16x16-1bpp.png
+== bmp-size-17x17-1bpp.bmp bmp-size-17x17-1bpp.png
+== bmp-size-31x31-1bpp.bmp bmp-size-31x31-1bpp.png
+== bmp-size-32x32-1bpp.bmp bmp-size-32x32-1bpp.png
+== bmp-size-33x33-1bpp.bmp bmp-size-33x33-1bpp.png
+== bmp-not-square-1bpp.bmp bmp-not-square-1bpp.png
+== os2bmp-size-32x32-1bpp.bmp bmp-size-32x32-1bpp.png
+== top-to-bottom-16x16-1bpp.bmp bmp-size-16x16-1bpp.png
diff --git a/image/test/reftest/bmp/bmp-1bpp/top-to-bottom-16x16-1bpp.bmp b/image/test/reftest/bmp/bmp-1bpp/top-to-bottom-16x16-1bpp.bmp
new file mode 100644
index 0000000000..8633ef2aaa
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-1bpp/top-to-bottom-16x16-1bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-not-square-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-not-square-24bpp.bmp
new file mode 100644
index 0000000000..9d1f4de2cd
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-not-square-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-not-square-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-not-square-24bpp.png
new file mode 100644
index 0000000000..9b0d160815
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-not-square-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-15x15-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-15x15-24bpp.bmp
new file mode 100644
index 0000000000..ba029510b3
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-15x15-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-15x15-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-15x15-24bpp.png
new file mode 100644
index 0000000000..e1287430d0
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-15x15-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-16x16-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-16x16-24bpp.bmp
new file mode 100644
index 0000000000..f35d706692
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-16x16-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-16x16-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-16x16-24bpp.png
new file mode 100644
index 0000000000..c04869e728
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-16x16-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-17x17-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-17x17-24bpp.bmp
new file mode 100644
index 0000000000..fc576c4980
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-17x17-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-17x17-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-17x17-24bpp.png
new file mode 100644
index 0000000000..00fb8e4f37
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-17x17-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-1x1-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-1x1-24bpp.bmp
new file mode 100644
index 0000000000..db790d50c0
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-1x1-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-1x1-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-1x1-24bpp.png
new file mode 100644
index 0000000000..c05f5fef89
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-1x1-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-2x2-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-2x2-24bpp.bmp
new file mode 100644
index 0000000000..19bff3d010
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-2x2-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-2x2-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-2x2-24bpp.png
new file mode 100644
index 0000000000..e512d3f9b4
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-2x2-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-31x31-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-31x31-24bpp.bmp
new file mode 100644
index 0000000000..da11048cb0
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-31x31-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-31x31-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-31x31-24bpp.png
new file mode 100644
index 0000000000..e4a8642514
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-31x31-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-32x32-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-32x32-24bpp.bmp
new file mode 100644
index 0000000000..e1631e5fdb
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-32x32-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-32x32-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-32x32-24bpp.png
new file mode 100644
index 0000000000..3a6fbe8ee9
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-32x32-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-33x33-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-33x33-24bpp.bmp
new file mode 100644
index 0000000000..d228cf0635
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-33x33-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-33x33-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-33x33-24bpp.png
new file mode 100644
index 0000000000..72ef7eb636
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-33x33-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-3x3-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-3x3-24bpp.bmp
new file mode 100644
index 0000000000..f353f9b6d3
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-3x3-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-3x3-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-3x3-24bpp.png
new file mode 100644
index 0000000000..cb42ec4f87
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-3x3-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-4x4-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-4x4-24bpp.bmp
new file mode 100644
index 0000000000..2373435f48
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-4x4-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-4x4-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-4x4-24bpp.png
new file mode 100644
index 0000000000..e6afafd89a
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-4x4-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-5x5-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-5x5-24bpp.bmp
new file mode 100644
index 0000000000..a3016fc1ab
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-5x5-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-5x5-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-5x5-24bpp.png
new file mode 100644
index 0000000000..a844aff76d
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-5x5-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-6x6-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-6x6-24bpp.bmp
new file mode 100644
index 0000000000..cba1d62cc7
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-6x6-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-6x6-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-6x6-24bpp.png
new file mode 100644
index 0000000000..415c2d9c6a
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-6x6-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-7x7-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-7x7-24bpp.bmp
new file mode 100644
index 0000000000..87cd419b40
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-7x7-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-7x7-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-7x7-24bpp.png
new file mode 100644
index 0000000000..ab2f892747
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-7x7-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-8x8-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-8x8-24bpp.bmp
new file mode 100644
index 0000000000..b6f108a044
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-8x8-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-8x8-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-8x8-24bpp.png
new file mode 100644
index 0000000000..fe2ff40a1d
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-8x8-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-9x9-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/bmp-size-9x9-24bpp.bmp
new file mode 100644
index 0000000000..8140b1905b
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-9x9-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/bmp-size-9x9-24bpp.png b/image/test/reftest/bmp/bmp-24bpp/bmp-size-9x9-24bpp.png
new file mode 100644
index 0000000000..18ab4b25de
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/bmp-size-9x9-24bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/os2bmp-size-32x32-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/os2bmp-size-32x32-24bpp.bmp
new file mode 100644
index 0000000000..b75ae62ca8
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/os2bmp-size-32x32-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-24bpp/reftest.list b/image/test/reftest/bmp/bmp-24bpp/reftest.list
new file mode 100644
index 0000000000..83ec17563b
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/reftest.list
@@ -0,0 +1,21 @@
+# BMP 24BPP tests
+
+# Images of various sizes
+== bmp-size-1x1-24bpp.bmp bmp-size-1x1-24bpp.png
+== bmp-size-2x2-24bpp.bmp bmp-size-2x2-24bpp.png
+== bmp-size-3x3-24bpp.bmp bmp-size-3x3-24bpp.png
+== bmp-size-4x4-24bpp.bmp bmp-size-4x4-24bpp.png
+== bmp-size-5x5-24bpp.bmp bmp-size-5x5-24bpp.png
+== bmp-size-6x6-24bpp.bmp bmp-size-6x6-24bpp.png
+== bmp-size-7x7-24bpp.bmp bmp-size-7x7-24bpp.png
+== bmp-size-8x8-24bpp.bmp bmp-size-8x8-24bpp.png
+== bmp-size-9x9-24bpp.bmp bmp-size-9x9-24bpp.png
+== bmp-size-15x15-24bpp.bmp bmp-size-15x15-24bpp.png
+== bmp-size-16x16-24bpp.bmp bmp-size-16x16-24bpp.png
+== bmp-size-17x17-24bpp.bmp bmp-size-17x17-24bpp.png
+== bmp-size-31x31-24bpp.bmp bmp-size-31x31-24bpp.png
+== bmp-size-32x32-24bpp.bmp bmp-size-32x32-24bpp.png
+== bmp-size-33x33-24bpp.bmp bmp-size-33x33-24bpp.png
+== bmp-not-square-24bpp.bmp bmp-not-square-24bpp.png
+== os2bmp-size-32x32-24bpp.bmp bmp-size-32x32-24bpp.png
+== top-to-bottom-16x16-24bpp.bmp bmp-size-16x16-24bpp.png
diff --git a/image/test/reftest/bmp/bmp-24bpp/top-to-bottom-16x16-24bpp.bmp b/image/test/reftest/bmp/bmp-24bpp/top-to-bottom-16x16-24bpp.bmp
new file mode 100644
index 0000000000..bd18f85d48
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-24bpp/top-to-bottom-16x16-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-not-square-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-not-square-4bpp.bmp
new file mode 100644
index 0000000000..f63dd81bde
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-not-square-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-not-square-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-not-square-4bpp.png
new file mode 100644
index 0000000000..7c713c557c
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-not-square-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-15x15-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-15x15-4bpp.bmp
new file mode 100644
index 0000000000..8b586dbfd6
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-15x15-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-15x15-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-15x15-4bpp.png
new file mode 100644
index 0000000000..5d4a3f9534
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-15x15-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-16x16-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-16x16-4bpp.bmp
new file mode 100644
index 0000000000..eae432e656
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-16x16-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-16x16-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-16x16-4bpp.png
new file mode 100644
index 0000000000..d45d63f539
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-16x16-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-17x17-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-17x17-4bpp.bmp
new file mode 100644
index 0000000000..5880c6111c
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-17x17-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-17x17-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-17x17-4bpp.png
new file mode 100644
index 0000000000..bf48903299
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-17x17-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-1x1-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-1x1-4bpp.bmp
new file mode 100644
index 0000000000..2ba68a3913
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-1x1-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-1x1-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-1x1-4bpp.png
new file mode 100644
index 0000000000..d41dd645b7
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-1x1-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-2x2-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-2x2-4bpp.bmp
new file mode 100644
index 0000000000..6c6383aa80
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-2x2-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-2x2-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-2x2-4bpp.png
new file mode 100644
index 0000000000..b2d6050415
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-2x2-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-31x31-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-31x31-4bpp.bmp
new file mode 100644
index 0000000000..ac440a6d8d
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-31x31-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-31x31-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-31x31-4bpp.png
new file mode 100644
index 0000000000..cb12a3448d
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-31x31-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-32x32-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-32x32-4bpp.bmp
new file mode 100644
index 0000000000..e4383c473a
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-32x32-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-32x32-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-32x32-4bpp.png
new file mode 100644
index 0000000000..58d867d120
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-32x32-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-33x33-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-33x33-4bpp.bmp
new file mode 100644
index 0000000000..04b2c1d1fd
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-33x33-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-33x33-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-33x33-4bpp.png
new file mode 100644
index 0000000000..064fde198c
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-33x33-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-3x3-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-3x3-4bpp.bmp
new file mode 100644
index 0000000000..179dbcfa59
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-3x3-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-3x3-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-3x3-4bpp.png
new file mode 100644
index 0000000000..e34114d5c9
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-3x3-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-4x4-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-4x4-4bpp.bmp
new file mode 100644
index 0000000000..0f57e102e2
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-4x4-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-4x4-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-4x4-4bpp.png
new file mode 100644
index 0000000000..3efa555620
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-4x4-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-5x5-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-5x5-4bpp.bmp
new file mode 100644
index 0000000000..a4efe66601
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-5x5-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-5x5-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-5x5-4bpp.png
new file mode 100644
index 0000000000..02ebf57a51
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-5x5-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-6x6-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-6x6-4bpp.bmp
new file mode 100644
index 0000000000..f4e1a29185
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-6x6-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-6x6-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-6x6-4bpp.png
new file mode 100644
index 0000000000..1f5769d09c
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-6x6-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-7x7-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-7x7-4bpp.bmp
new file mode 100644
index 0000000000..e7ee1cf20a
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-7x7-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-7x7-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-7x7-4bpp.png
new file mode 100644
index 0000000000..59a1b98b52
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-7x7-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-8x8-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-8x8-4bpp.bmp
new file mode 100644
index 0000000000..aa6959baf5
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-8x8-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-8x8-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-8x8-4bpp.png
new file mode 100644
index 0000000000..cf44f59676
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-8x8-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-9x9-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/bmp-size-9x9-4bpp.bmp
new file mode 100644
index 0000000000..65ec12a376
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-9x9-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/bmp-size-9x9-4bpp.png b/image/test/reftest/bmp/bmp-4bpp/bmp-size-9x9-4bpp.png
new file mode 100644
index 0000000000..2e07364135
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/bmp-size-9x9-4bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/os2bmp-size-32x32-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/os2bmp-size-32x32-4bpp.bmp
new file mode 100644
index 0000000000..08fc30d5fc
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/os2bmp-size-32x32-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/reftest.list b/image/test/reftest/bmp/bmp-4bpp/reftest.list
new file mode 100644
index 0000000000..4a1785e86f
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/reftest.list
@@ -0,0 +1,24 @@
+# BMP 4BPP tests
+
+# Images of various sizes
+== bmp-size-1x1-4bpp.bmp bmp-size-1x1-4bpp.png
+== bmp-size-2x2-4bpp.bmp bmp-size-2x2-4bpp.png
+== bmp-size-3x3-4bpp.bmp bmp-size-3x3-4bpp.png
+== bmp-size-4x4-4bpp.bmp bmp-size-4x4-4bpp.png
+== bmp-size-5x5-4bpp.bmp bmp-size-5x5-4bpp.png
+== bmp-size-6x6-4bpp.bmp bmp-size-6x6-4bpp.png
+== bmp-size-7x7-4bpp.bmp bmp-size-7x7-4bpp.png
+== bmp-size-8x8-4bpp.bmp bmp-size-8x8-4bpp.png
+== bmp-size-9x9-4bpp.bmp bmp-size-9x9-4bpp.png
+== bmp-size-15x15-4bpp.bmp bmp-size-15x15-4bpp.png
+== bmp-size-16x16-4bpp.bmp bmp-size-16x16-4bpp.png
+== bmp-size-17x17-4bpp.bmp bmp-size-17x17-4bpp.png
+== bmp-size-31x31-4bpp.bmp bmp-size-31x31-4bpp.png
+== bmp-size-32x32-4bpp.bmp bmp-size-32x32-4bpp.png
+== bmp-size-33x33-4bpp.bmp bmp-size-33x33-4bpp.png
+== bmp-not-square-4bpp.bmp bmp-not-square-4bpp.png
+== os2bmp-size-32x32-4bpp.bmp bmp-size-32x32-4bpp.png
+== top-to-bottom-16x16-4bpp.bmp bmp-size-16x16-4bpp.png
+# test that delta skips are drawn as transparent
+# taken from http://bmptestsuite.sourceforge.net/
+== rle4-delta-320x240.bmp rle4-delta-320x240.png
diff --git a/image/test/reftest/bmp/bmp-4bpp/rle4-delta-320x240.bmp b/image/test/reftest/bmp/bmp-4bpp/rle4-delta-320x240.bmp
new file mode 100644
index 0000000000..78a0927870
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/rle4-delta-320x240.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/rle4-delta-320x240.png b/image/test/reftest/bmp/bmp-4bpp/rle4-delta-320x240.png
new file mode 100644
index 0000000000..f9a3ceae23
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/rle4-delta-320x240.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-4bpp/top-to-bottom-16x16-4bpp.bmp b/image/test/reftest/bmp/bmp-4bpp/top-to-bottom-16x16-4bpp.bmp
new file mode 100644
index 0000000000..c77696b325
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-4bpp/top-to-bottom-16x16-4bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-extrapad-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-extrapad-8bpp.png
new file mode 100644
index 0000000000..827de11a52
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-extrapad-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-not-square-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-not-square-8bpp.bmp
new file mode 100644
index 0000000000..d7a99164c2
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-not-square-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-not-square-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-not-square-8bpp.png
new file mode 100644
index 0000000000..be45f19d50
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-not-square-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-15x15-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-15x15-8bpp.bmp
new file mode 100644
index 0000000000..8dac8ec86c
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-15x15-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-15x15-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-15x15-8bpp.png
new file mode 100644
index 0000000000..ce00553055
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-15x15-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-16x16-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-16x16-8bpp.bmp
new file mode 100644
index 0000000000..bb60249ac8
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-16x16-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-16x16-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-16x16-8bpp.png
new file mode 100644
index 0000000000..6a2394618f
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-16x16-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-17x17-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-17x17-8bpp.bmp
new file mode 100644
index 0000000000..b817888510
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-17x17-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-17x17-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-17x17-8bpp.png
new file mode 100644
index 0000000000..494cd96cd6
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-17x17-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-1x1-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-1x1-8bpp.bmp
new file mode 100644
index 0000000000..9f3ef5136b
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-1x1-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-1x1-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-1x1-8bpp.png
new file mode 100644
index 0000000000..a7553a73f7
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-1x1-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-2x2-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-2x2-8bpp.bmp
new file mode 100644
index 0000000000..63d3f1c058
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-2x2-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-2x2-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-2x2-8bpp.png
new file mode 100644
index 0000000000..17257e9924
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-2x2-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-31x31-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-31x31-8bpp.bmp
new file mode 100644
index 0000000000..e4fd01fe0d
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-31x31-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-31x31-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-31x31-8bpp.png
new file mode 100644
index 0000000000..d43ac83900
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-31x31-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-32x32-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-32x32-8bpp.bmp
new file mode 100644
index 0000000000..d2f800d673
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-32x32-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-32x32-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-32x32-8bpp.png
new file mode 100644
index 0000000000..03642849aa
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-32x32-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-33x33-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-33x33-8bpp.bmp
new file mode 100644
index 0000000000..19b0744dbf
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-33x33-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-33x33-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-33x33-8bpp.png
new file mode 100644
index 0000000000..078b56df0d
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-33x33-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-3x3-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-3x3-8bpp.bmp
new file mode 100644
index 0000000000..9f15f35831
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-3x3-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-3x3-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-3x3-8bpp.png
new file mode 100644
index 0000000000..ba34b2601b
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-3x3-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-4x4-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-4x4-8bpp.bmp
new file mode 100644
index 0000000000..1ad7a8de11
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-4x4-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-4x4-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-4x4-8bpp.png
new file mode 100644
index 0000000000..ecf9e5e795
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-4x4-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-5x5-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-5x5-8bpp.bmp
new file mode 100644
index 0000000000..6eb759d061
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-5x5-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-5x5-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-5x5-8bpp.png
new file mode 100644
index 0000000000..1a440a16bd
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-5x5-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-6x6-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-6x6-8bpp.bmp
new file mode 100644
index 0000000000..a1e0e2415a
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-6x6-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-6x6-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-6x6-8bpp.png
new file mode 100644
index 0000000000..e0ac1a8f6d
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-6x6-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-7x7-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-7x7-8bpp.bmp
new file mode 100644
index 0000000000..25c59d7350
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-7x7-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-7x7-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-7x7-8bpp.png
new file mode 100644
index 0000000000..51c7642656
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-7x7-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-8x8-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-8x8-8bpp.bmp
new file mode 100644
index 0000000000..ff5b7681c8
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-8x8-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-8x8-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-8x8-8bpp.png
new file mode 100644
index 0000000000..77dc7782e4
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-8x8-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-9x9-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/bmp-size-9x9-8bpp.bmp
new file mode 100644
index 0000000000..006961628f
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-9x9-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/bmp-size-9x9-8bpp.png b/image/test/reftest/bmp/bmp-8bpp/bmp-size-9x9-8bpp.png
new file mode 100644
index 0000000000..93914c3e16
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/bmp-size-9x9-8bpp.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/os2-bmp-size-32x32-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/os2-bmp-size-32x32-8bpp.bmp
new file mode 100644
index 0000000000..b6df221e1b
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/os2-bmp-size-32x32-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/reftest.list b/image/test/reftest/bmp/bmp-8bpp/reftest.list
new file mode 100644
index 0000000000..6fcef4742a
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/reftest.list
@@ -0,0 +1,25 @@
+# BMP 8BPP tests
+
+# Images of various sizes
+== bmp-size-1x1-8bpp.bmp bmp-size-1x1-8bpp.png
+== bmp-size-2x2-8bpp.bmp bmp-size-2x2-8bpp.png
+== bmp-size-3x3-8bpp.bmp bmp-size-3x3-8bpp.png
+== bmp-size-4x4-8bpp.bmp bmp-size-4x4-8bpp.png
+== bmp-size-5x5-8bpp.bmp bmp-size-5x5-8bpp.png
+== bmp-size-6x6-8bpp.bmp bmp-size-6x6-8bpp.png
+== bmp-size-7x7-8bpp.bmp bmp-size-7x7-8bpp.png
+== bmp-size-8x8-8bpp.bmp bmp-size-8x8-8bpp.png
+== bmp-size-9x9-8bpp.bmp bmp-size-9x9-8bpp.png
+== bmp-size-15x15-8bpp.bmp bmp-size-15x15-8bpp.png
+== bmp-size-16x16-8bpp.bmp bmp-size-16x16-8bpp.png
+== bmp-size-17x17-8bpp.bmp bmp-size-17x17-8bpp.png
+== bmp-size-31x31-8bpp.bmp bmp-size-31x31-8bpp.png
+== bmp-size-32x32-8bpp.bmp bmp-size-32x32-8bpp.png
+== bmp-size-33x33-8bpp.bmp bmp-size-33x33-8bpp.png
+== bmp-not-square-8bpp.bmp bmp-not-square-8bpp.png
+== rle-bmp-extrapad-8bpp.bmp bmp-extrapad-8bpp.png
+== rle-bmp-not-square-8bpp.bmp bmp-not-square-8bpp.png
+== os2-bmp-size-32x32-8bpp.bmp bmp-size-32x32-8bpp.png
+== rle-bmp-size-32x32-8bpp.bmp bmp-size-32x32-8bpp.png
+== top-to-bottom-rle-bmp-size-32x32-8bpp.bmp bmp-size-32x32-8bpp.png
+== top-to-bottom-16x16-8bpp.bmp bmp-size-16x16-8bpp.png
diff --git a/image/test/reftest/bmp/bmp-8bpp/rle-bmp-extrapad-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/rle-bmp-extrapad-8bpp.bmp
new file mode 100644
index 0000000000..9550ab2af6
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/rle-bmp-extrapad-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/rle-bmp-not-square-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/rle-bmp-not-square-8bpp.bmp
new file mode 100644
index 0000000000..8687aab6cf
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/rle-bmp-not-square-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/rle-bmp-size-32x32-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/rle-bmp-size-32x32-8bpp.bmp
new file mode 100644
index 0000000000..bd793b6b66
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/rle-bmp-size-32x32-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/top-to-bottom-16x16-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/top-to-bottom-16x16-8bpp.bmp
new file mode 100644
index 0000000000..bb60249ac8
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/top-to-bottom-16x16-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-8bpp/top-to-bottom-rle-bmp-size-32x32-8bpp.bmp b/image/test/reftest/bmp/bmp-8bpp/top-to-bottom-rle-bmp-size-32x32-8bpp.bmp
new file mode 100644
index 0000000000..396672ea15
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-8bpp/top-to-bottom-rle-bmp-size-32x32-8bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-corrupted/invalid-bpp.bmp b/image/test/reftest/bmp/bmp-corrupted/invalid-bpp.bmp
new file mode 100644
index 0000000000..c00dd3fa4c
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-corrupted/invalid-bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-corrupted/invalid-compression-BITFIELDS.bmp b/image/test/reftest/bmp/bmp-corrupted/invalid-compression-BITFIELDS.bmp
new file mode 100644
index 0000000000..92a7225261
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-corrupted/invalid-compression-BITFIELDS.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-corrupted/invalid-compression-RLE4.bmp b/image/test/reftest/bmp/bmp-corrupted/invalid-compression-RLE4.bmp
new file mode 100644
index 0000000000..d73c89411d
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-corrupted/invalid-compression-RLE4.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-corrupted/invalid-compression-RLE8.bmp b/image/test/reftest/bmp/bmp-corrupted/invalid-compression-RLE8.bmp
new file mode 100644
index 0000000000..5a88064543
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-corrupted/invalid-compression-RLE8.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-corrupted/invalid-compression.bmp b/image/test/reftest/bmp/bmp-corrupted/invalid-compression.bmp
new file mode 100644
index 0000000000..aa3134e562
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-corrupted/invalid-compression.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-corrupted/invalid-data-offset.bmp b/image/test/reftest/bmp/bmp-corrupted/invalid-data-offset.bmp
new file mode 100644
index 0000000000..b89bc55a8e
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-corrupted/invalid-data-offset.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-corrupted/invalid-signature.bmp b/image/test/reftest/bmp/bmp-corrupted/invalid-signature.bmp
new file mode 100644
index 0000000000..6eebb57180
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-corrupted/invalid-signature.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-corrupted/invalid-truncated-metadata.bmp b/image/test/reftest/bmp/bmp-corrupted/invalid-truncated-metadata.bmp
new file mode 100644
index 0000000000..228c5c9992
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-corrupted/invalid-truncated-metadata.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-corrupted/os2-invalid-bpp.bmp b/image/test/reftest/bmp/bmp-corrupted/os2-invalid-bpp.bmp
new file mode 100644
index 0000000000..af4678a284
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-corrupted/os2-invalid-bpp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmp-corrupted/reftest.list b/image/test/reftest/bmp/bmp-corrupted/reftest.list
new file mode 100644
index 0000000000..882657983a
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-corrupted/reftest.list
@@ -0,0 +1,21 @@
+# Corrupted BMP tests
+
+== wrapper.html?invalid-signature.bmp about:blank
+== wrapper.html?invalid-bpp.bmp about:blank
+== wrapper.html?os2-invalid-bpp.bmp about:blank
+# Tests for an unsupported compression value
+== wrapper.html?invalid-compression.bmp about:blank
+# Tests for RLE4 with an invalid BPP
+== wrapper.html?invalid-compression-RLE4.bmp about:blank
+# Tests for RLE8 with an invalid BPP
+== wrapper.html?invalid-compression-RLE8.bmp about:blank
+
+# Test for BITFIELDS with an invalid BIH size. (This is the obscure
+# BITMAPV3INFOHEADER variant mentioned in
+# https://en.wikipedia.org/wiki/BMP_file_format which we don't accept.)
+== wrapper.html?invalid-compression-BITFIELDS.bmp about:blank
+
+== wrapper.html?invalid-truncated-metadata.bmp about:blank
+
+# Test for an invalid data offset
+== wrapper.html?invalid-data-offset.bmp about:blank \ No newline at end of file
diff --git a/image/test/reftest/bmp/bmp-corrupted/wrapper.html b/image/test/reftest/bmp/bmp-corrupted/wrapper.html
new file mode 100644
index 0000000000..22b74c8fc1
--- /dev/null
+++ b/image/test/reftest/bmp/bmp-corrupted/wrapper.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Image reftest wrapper</title>
+<style type="text/css">
+ #image1 { background-color: rgb(10, 100, 250); }
+</style>
+<script>
+ // The image is loaded async after the page loads
+ // wait for it to finish loading
+ function onImageLoad() {
+ document.documentElement.removeAttribute("class");
+ };
+</script>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img id="image1" alt=" ">
+<script>
+ // Use as "wrapper.html?image.png"
+ var imgURL = document.location.search.substr(1);
+ document.images[0].onload = onImageLoad;
+ document.images[0].onerror = onImageLoad;
+ document.images[0].src = imgURL;
+</script>
+</body>
+</html>
+
diff --git a/image/test/reftest/bmp/bmpsuite/COPYING.txt b/image/test/reftest/bmp/bmpsuite/COPYING.txt
new file mode 100644
index 0000000000..10926e87f1
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/COPYING.txt
@@ -0,0 +1,675 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
diff --git a/image/test/reftest/bmp/bmpsuite/README.mozilla b/image/test/reftest/bmp/bmpsuite/README.mozilla
new file mode 100644
index 0000000000..f59a494c26
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/README.mozilla
@@ -0,0 +1,40 @@
+bmpsuite, by Jason Summers, is an excellent BMP test suite that covers many
+obscure corners of the BMP format. All the test images can be seen here:
+
+ http://entropymine.com/jason/bmpsuite/bmpsuite/html/bmpsuite.html
+
+The code used to generate the test images is available here:
+
+ https://github.com/jsummers/bmpsuite/
+
+The readme.txt file states that the code is GPLv3 and the generated image files
+are in the public domain. We have not included the code, but we have included:
+(a) some quotes from the documentation and (b) some of the reference PNG
+images. However, (a) and (b) are for testing purposes only and are not included
+in Firefox releases.
+
+The BMP files within this directory were generated with bmpsuite v2.3 (git
+revision 3adcc9e20c0b6d2d665966b7e047b6f9474cef12).
+
+There are three sub-directories.
+- g/: for "good" images.
+- q/: for "questionable" images.
+- b/: for "bad" images.
+- x/: for images that arguably may not truly be in "BMP format".
+
+Each file listed in a reftest.list file is annotated with the following lines.
+
+- The first line starts with "BMP:" and is the output of the MOZ_LOG call in
+ nsBMPDecoder.cpp. It has basic image info.
+
+- Next is a quote from the bmpsuite docs, which describes the particulars of
+ the file.
+
+- Some files also have additional notes in square brackets. These explain
+ anything non-obvious about the file, such as how we handle things that are
+ ambiguous, any shortcomings in our decoding, and how Chromium handles the
+ image.
+
+Some of the reference PNGs need a small amount of fuzziness to match the BMPs.
+This might be due to PNG color correction.
+
diff --git a/image/test/reftest/bmp/bmpsuite/b/badbitcount.bmp b/image/test/reftest/bmp/bmpsuite/b/badbitcount.bmp
new file mode 100644
index 0000000000..d4fa4e8b88
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badbitcount.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badbitssize.bmp b/image/test/reftest/bmp/bmpsuite/b/badbitssize.bmp
new file mode 100644
index 0000000000..0a99a605af
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badbitssize.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/baddens1.bmp b/image/test/reftest/bmp/bmpsuite/b/baddens1.bmp
new file mode 100644
index 0000000000..a6150a6fe7
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/baddens1.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/baddens2.bmp b/image/test/reftest/bmp/bmpsuite/b/baddens2.bmp
new file mode 100644
index 0000000000..f2c1dfb665
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/baddens2.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badfilesize.bmp b/image/test/reftest/bmp/bmpsuite/b/badfilesize.bmp
new file mode 100644
index 0000000000..da52cb51d7
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badfilesize.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badheadersize.bmp b/image/test/reftest/bmp/bmpsuite/b/badheadersize.bmp
new file mode 100644
index 0000000000..2a4083a6f9
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badheadersize.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badpalettesize.bmp b/image/test/reftest/bmp/bmpsuite/b/badpalettesize.bmp
new file mode 100644
index 0000000000..7d9d1b745d
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badpalettesize.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badplanes.bmp b/image/test/reftest/bmp/bmpsuite/b/badplanes.bmp
new file mode 100644
index 0000000000..92d2855b62
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badplanes.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badrle.bmp b/image/test/reftest/bmp/bmpsuite/b/badrle.bmp
new file mode 100644
index 0000000000..cbf8fdc2e1
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badrle.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badrle.png b/image/test/reftest/bmp/bmpsuite/b/badrle.png
new file mode 100644
index 0000000000..1764ef9f98
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badrle.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badrle4.bmp b/image/test/reftest/bmp/bmpsuite/b/badrle4.bmp
new file mode 100644
index 0000000000..632787a730
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badrle4.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badrle4.png b/image/test/reftest/bmp/bmpsuite/b/badrle4.png
new file mode 100644
index 0000000000..7f5af39fe0
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badrle4.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badrle4bis.bmp b/image/test/reftest/bmp/bmpsuite/b/badrle4bis.bmp
new file mode 100644
index 0000000000..130b7e659c
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badrle4bis.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badrle4bis.png b/image/test/reftest/bmp/bmpsuite/b/badrle4bis.png
new file mode 100644
index 0000000000..7d0d95871a
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badrle4bis.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badrle4ter.bmp b/image/test/reftest/bmp/bmpsuite/b/badrle4ter.bmp
new file mode 100644
index 0000000000..8107a335fc
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badrle4ter.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badrle4ter.png b/image/test/reftest/bmp/bmpsuite/b/badrle4ter.png
new file mode 100644
index 0000000000..230bb60f47
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badrle4ter.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badrlebis.bmp b/image/test/reftest/bmp/bmpsuite/b/badrlebis.bmp
new file mode 100644
index 0000000000..893eb11ab7
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badrlebis.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badrlebis.png b/image/test/reftest/bmp/bmpsuite/b/badrlebis.png
new file mode 100644
index 0000000000..f0094a1156
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badrlebis.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badrleter.bmp b/image/test/reftest/bmp/bmpsuite/b/badrleter.bmp
new file mode 100644
index 0000000000..04d5874e67
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badrleter.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badrleter.png b/image/test/reftest/bmp/bmpsuite/b/badrleter.png
new file mode 100644
index 0000000000..359bc12e12
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badrleter.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/badwidth.bmp b/image/test/reftest/bmp/bmpsuite/b/badwidth.bmp
new file mode 100644
index 0000000000..9fca005dc3
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/badwidth.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/pal1.png b/image/test/reftest/bmp/bmpsuite/b/pal1.png
new file mode 100644
index 0000000000..89a433ed76
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/pal1.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/pal8.png b/image/test/reftest/bmp/bmpsuite/b/pal8.png
new file mode 100644
index 0000000000..2bfd3e650f
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/pal8.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/pal8badindex.bmp b/image/test/reftest/bmp/bmpsuite/b/pal8badindex.bmp
new file mode 100644
index 0000000000..efe16c05c1
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/pal8badindex.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/pal8badindex.png b/image/test/reftest/bmp/bmpsuite/b/pal8badindex.png
new file mode 100644
index 0000000000..0efb392b9e
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/pal8badindex.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/reallybig.bmp b/image/test/reftest/bmp/bmpsuite/b/reallybig.bmp
new file mode 100644
index 0000000000..101e0b4943
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/reallybig.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/reftest.list b/image/test/reftest/bmp/bmpsuite/b/reftest.list
new file mode 100644
index 0000000000..c892288b40
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/reftest.list
@@ -0,0 +1,110 @@
+# bmpsuite "bad" tests
+
+# See ../README.mozilla for details.
+
+# BMP: bihsize=40, 127 x 64, bpp=30000, compression=0, colors=2
+# "Header indicates an absurdly large number of bits/pixel."
+# [We reject it. So does Chromium.]
+== wrapper.html?badbitcount.bmp about:blank
+
+# BMP: bihsize=40, 127 x 64, bpp=1, compression=0, colors=2
+# "Header incorrectly indicates that the bitmap is several GB in size."
+# [We accept it. So does Chromium.]
+fuzzy(0-1,0-926) == badbitssize.bmp pal1.png
+
+# BMP: bihsize=40, 127 x 64, bpp=1, compression=0, colors=2
+# BMP: bihsize=40, 127 x 64, bpp=1, compression=0, colors=2
+# "Density (pixels per meter) suggests the image is much larger in one
+# dimension than the other."
+# [We accept them. So does Chromium.]
+== baddens1.bmp pal1.png
+== baddens2.bmp pal1.png
+
+# BMP: bihsize=40, 127 x 64, bpp=1, compression=0, colors=2
+# "Header incorrectly indicates that the file is several GB in size."
+# [We accept it. So does Chromium.]
+== badfilesize.bmp pal1.png
+
+# BMP: <no "BMP:" output is produced for files with bad header sizes>
+# "Header size is 66 bytes, which is not a valid size for any known BMP
+# version."
+# [We reject it. So does Chromium.]
+== wrapper.html?badheadersize.bmp about:blank
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=0, colors=305402420
+# "Header incorrectly indicates that the palette contains an absurdly large
+# number of colors."
+# [We reject it. Chromium accepts it but draws nothing. Rejecting seems
+# preferable give that the data is clearly untrustworthy.]
+fuzzy(0-245,0-8128) == wrapper.html?badpalettesize.bmp about:blank
+
+# BMP: bihsize=40, 127 x 64, bpp=1, compression=0, colors=2
+# "The 'planes' setting, which is required to be 1, is not 1."
+# [We accept it. So does Chromium.]
+== badplanes.bmp pal1.png
+
+# BMP: bihsize=40, 127 x 64, bpp=4, compression=2, colors=13
+# "An invalid RLE4-compressed image that tries to cause buffer overruns."
+== badrle4.bmp badrle4.png
+
+# BMP: bihsize=40, 127 x 64, bpp=4, compression=2, colors=13
+# "Another invalid RLE4-compressed image that tries to cause buffer overruns."
+== badrle4bis.bmp badrle4bis.png
+
+# BMP: bihsize=40, 127 x 64, bpp=4, compression=2, colors=13
+# "Another invalid RLE4-compressed image that tries to cause buffer overruns."
+== badrle4ter.bmp badrle4ter.png
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=1, colors=253
+# "An invalid RLE-compressed image that tries to cause buffer overruns."
+# [We accept it, drawing the valid first part and leaving the rest black.
+# Chromium accepts it, drawing the valid first part and leaving the rest
+# transparent. Using black for the invalid part is arguably better because it
+# makes the image edges more obvious.]
+== badrle.bmp badrle.png
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=1, colors=253
+# "8-bit version of b/badrle4bis.bmp."
+== badrlebis.bmp badrlebis.png
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=1, colors=253
+# "8-bit version of b/badrle4ter.bmp."
+== badrleter.bmp badrleter.png
+
+# BMP: bihsize=40, -127 x 64, bpp=1, compression=0, colors=2
+# "The image claims to be a negative number of pixels in width."
+# [We reject it. So does Chromium.]
+== wrapper.html?badwidth.bmp about:blank
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=0, colors=101
+# "Many of the palette indices used in the image are not present in the
+# palette."
+# [We accept it and use black for the missing colors. So does Chromium.]
+== pal8badindex.bmp pal8badindex.png
+
+# BMP: bihsize=40, 3000000 x 2000000, bpp=24, compression=0, colors=0
+# "An image with a very large reported width and height."
+# [We reject it. So does Chromium.]
+== wrapper.html?reallybig.bmp about:blank
+
+# BMP: bihsize=40, 127 x 64, bpp=16, compression=3, colors=0
+# "A 16-bit image with a BITFIELDS segment indicating 8 red, 8 green, and 0
+# blue bits. The documentation doesn’t say whether undefined channels are
+# legal, or how they should be handled."
+== rgb16-880.bmp rgb16-880.png
+
+# BMP: bihsize=40, 127 x -64, bpp=8, compression=1, colors=252
+# "An RLE-compressed image that tries to use top-down orientation, which isn’t
+# allowed."
+# [We accept it. Chromium rejects it. Accepting seems better given that we can
+# decode it perfectly well.]
+fuzzy(0-1,0-996) == rletopdown.bmp pal8.png
+
+# BMP: bihsize=40, 127 x 64, bpp=1, compression=0, colors=2
+# "A file that has been truncated in the middle of the bitmap."
+# [We accept it, drawing the part that is present and leaving the rest black.
+# Chromium draws the part that is present and leaves the rest transparent.
+# Using black for the invalid part is arguably better because it makes the
+# image edges more obvious.]
+== shortfile.bmp shortfile.png
+
diff --git a/image/test/reftest/bmp/bmpsuite/b/rgb16-880.bmp b/image/test/reftest/bmp/bmpsuite/b/rgb16-880.bmp
new file mode 100644
index 0000000000..72e7ce0eaf
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/rgb16-880.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/rgb16-880.png b/image/test/reftest/bmp/bmpsuite/b/rgb16-880.png
new file mode 100644
index 0000000000..9450eba2bb
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/rgb16-880.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/rletopdown.bmp b/image/test/reftest/bmp/bmpsuite/b/rletopdown.bmp
new file mode 100644
index 0000000000..21a909fda9
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/rletopdown.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/shortfile.bmp b/image/test/reftest/bmp/bmpsuite/b/shortfile.bmp
new file mode 100644
index 0000000000..73960797b9
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/shortfile.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/shortfile.png b/image/test/reftest/bmp/bmpsuite/b/shortfile.png
new file mode 100644
index 0000000000..0ec21d9295
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/shortfile.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/b/wrapper.html b/image/test/reftest/bmp/bmpsuite/b/wrapper.html
new file mode 100644
index 0000000000..22b74c8fc1
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/b/wrapper.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Image reftest wrapper</title>
+<style type="text/css">
+ #image1 { background-color: rgb(10, 100, 250); }
+</style>
+<script>
+ // The image is loaded async after the page loads
+ // wait for it to finish loading
+ function onImageLoad() {
+ document.documentElement.removeAttribute("class");
+ };
+</script>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img id="image1" alt=" ">
+<script>
+ // Use as "wrapper.html?image.png"
+ var imgURL = document.location.search.substr(1);
+ document.images[0].onload = onImageLoad;
+ document.images[0].onerror = onImageLoad;
+ document.images[0].src = imgURL;
+</script>
+</body>
+</html>
+
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal1.bmp b/image/test/reftest/bmp/bmpsuite/g/pal1.bmp
new file mode 100644
index 0000000000..4776f82778
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal1.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal1.png b/image/test/reftest/bmp/bmpsuite/g/pal1.png
new file mode 100644
index 0000000000..89a433ed76
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal1.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal1bg.bmp b/image/test/reftest/bmp/bmpsuite/g/pal1bg.bmp
new file mode 100644
index 0000000000..466d0ba727
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal1bg.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal1bg.png b/image/test/reftest/bmp/bmpsuite/g/pal1bg.png
new file mode 100644
index 0000000000..20c4bb838f
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal1bg.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal1wb.bmp b/image/test/reftest/bmp/bmpsuite/g/pal1wb.bmp
new file mode 100644
index 0000000000..56cb93203e
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal1wb.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal4.bmp b/image/test/reftest/bmp/bmpsuite/g/pal4.bmp
new file mode 100644
index 0000000000..7fd36303ca
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal4.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal4.png b/image/test/reftest/bmp/bmpsuite/g/pal4.png
new file mode 100644
index 0000000000..188bb0499e
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal4.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal4gs.bmp b/image/test/reftest/bmp/bmpsuite/g/pal4gs.bmp
new file mode 100644
index 0000000000..813268ca77
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal4gs.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal4gs.png b/image/test/reftest/bmp/bmpsuite/g/pal4gs.png
new file mode 100644
index 0000000000..3a9fc855e4
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal4gs.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal4rle.bmp b/image/test/reftest/bmp/bmpsuite/g/pal4rle.bmp
new file mode 100644
index 0000000000..a5672aebd6
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal4rle.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8-0.bmp b/image/test/reftest/bmp/bmpsuite/g/pal8-0.bmp
new file mode 100644
index 0000000000..ab8815a360
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8-0.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8.bmp b/image/test/reftest/bmp/bmpsuite/g/pal8.bmp
new file mode 100644
index 0000000000..96b2f86680
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8.png b/image/test/reftest/bmp/bmpsuite/g/pal8.png
new file mode 100644
index 0000000000..2bfd3e650f
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8gs.bmp b/image/test/reftest/bmp/bmpsuite/g/pal8gs.bmp
new file mode 100644
index 0000000000..66a0d70dc3
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8gs.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8gs.png b/image/test/reftest/bmp/bmpsuite/g/pal8gs.png
new file mode 100644
index 0000000000..b33b38e1d3
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8gs.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8nonsquare-e.png b/image/test/reftest/bmp/bmpsuite/g/pal8nonsquare-e.png
new file mode 100644
index 0000000000..646665f2d0
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8nonsquare-e.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8nonsquare.bmp b/image/test/reftest/bmp/bmpsuite/g/pal8nonsquare.bmp
new file mode 100644
index 0000000000..0aa8de04cb
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8nonsquare.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8nonsquare.png b/image/test/reftest/bmp/bmpsuite/g/pal8nonsquare.png
new file mode 100644
index 0000000000..9648cb6825
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8nonsquare.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8os2.bmp b/image/test/reftest/bmp/bmpsuite/g/pal8os2.bmp
new file mode 100644
index 0000000000..14901b3882
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8os2.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8rle.bmp b/image/test/reftest/bmp/bmpsuite/g/pal8rle.bmp
new file mode 100644
index 0000000000..d43101490f
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8rle.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8topdown.bmp b/image/test/reftest/bmp/bmpsuite/g/pal8topdown.bmp
new file mode 100644
index 0000000000..4b2f8e019f
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8topdown.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8v4.bmp b/image/test/reftest/bmp/bmpsuite/g/pal8v4.bmp
new file mode 100644
index 0000000000..34ebb8030c
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8v4.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8v5.bmp b/image/test/reftest/bmp/bmpsuite/g/pal8v5.bmp
new file mode 100644
index 0000000000..c54647a31a
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8v5.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8w124.bmp b/image/test/reftest/bmp/bmpsuite/g/pal8w124.bmp
new file mode 100644
index 0000000000..b7cc2d8bf7
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8w124.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8w124.png b/image/test/reftest/bmp/bmpsuite/g/pal8w124.png
new file mode 100644
index 0000000000..f80236df60
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8w124.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8w125.bmp b/image/test/reftest/bmp/bmpsuite/g/pal8w125.bmp
new file mode 100644
index 0000000000..06efed7443
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8w125.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8w125.png b/image/test/reftest/bmp/bmpsuite/g/pal8w125.png
new file mode 100644
index 0000000000..2a45116b91
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8w125.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8w126.bmp b/image/test/reftest/bmp/bmpsuite/g/pal8w126.bmp
new file mode 100644
index 0000000000..112aa9fe67
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8w126.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/pal8w126.png b/image/test/reftest/bmp/bmpsuite/g/pal8w126.png
new file mode 100644
index 0000000000..a41eab93d0
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/pal8w126.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/reftest.list b/image/test/reftest/bmp/bmpsuite/g/reftest.list
new file mode 100644
index 0000000000..d14c5aa42e
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/reftest.list
@@ -0,0 +1,129 @@
+# bmpsuite "good" tests
+
+# See ../README.mozilla for details.
+
+# BMP: bihsize=40, 127 x 64, bpp=1, compression=0, colors=2
+# "1 bit/pixel paletted image, in which black is the first color in the
+# palette."
+fuzzy(0-1,0-926) == pal1.bmp pal1.png
+
+# BMP: bihsize=40, 127 x 64, bpp=1, compression=0, colors=2
+# "1 bit/pixel paletted image, in which white is the first color in the
+# palette."
+fuzzy(0-1,0-926) == pal1wb.bmp pal1.png
+
+# BMP: bihsize=40, 127 x 64, bpp=1, compression=0, colors=2
+# "1 bit/pixel paletted image, with colors other than black and white."
+== pal1bg.bmp pal1bg.png
+
+# BMP: bihsize=40, 127 x 64, bpp=4, compression=0, colors=12
+# "Paletted image with 12 palette colors, and 4 bits/pixel."
+== pal4.bmp pal4.png
+
+# BMP: bihsize=40, 127 x 64, bpp=4, compression=0, colors=12
+# "Paletted image with 12 grayscale palette colors, and 4 bits/pixel."
+== pal4gs.bmp pal4gs.png
+
+# BMP: bihsize=40, 127 x 64, bpp=4, compression=2, colors=12
+# "4-bit image that uses RLE compression."
+== pal4rle.bmp pal4.png
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=0, colors=252
+# "Our standard paletted image, with 252 palette colors, and 8 bits/pixel."
+fuzzy(0-1,0-996) == pal8.bmp pal8.png
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=0, colors=0
+# "Every field that can be set to 0 is set to 0: pixels/meter=0; colors used=0
+# (meaning the default 256); size-of-image=0."
+fuzzy(0-1,0-996) == pal8-0.bmp pal8.png
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=0, colors=252
+# "An 8-bit image with a palette of 252 grayscale colors."
+== pal8gs.bmp pal8gs.png
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=1, colors=252
+# "8-bit image that uses RLE compression."
+fuzzy(0-1,0-996) == pal8rle.bmp pal8.png
+
+# BMP: bihsize=40, 126 x 63, bpp=8, compression=0, colors=252
+# BMP: bihsize=40, 125 x 62, bpp=8, compression=0, colors=252
+# BMP: bihsize=40, 124 x 61, bpp=8, compression=0, colors=252
+# "Images with different widths and heights. In BMP format, rows are padded to
+# a multiple of four bytes, so we test all four possibilities."
+fuzzy(0-1,0-889) == pal8w126.bmp pal8w126.png
+fuzzy(0-1,0-974) == pal8w125.bmp pal8w125.png
+fuzzy(0-1,0-870) == pal8w124.bmp pal8w124.png
+
+# BMP: bihsize=40, 127 x -64, bpp=8, compression=0, colors=252
+# "BMP images are normally stored from the bottom up, but there is a way to
+# store them from the top down."
+fuzzy(0-1,0-996) == pal8topdown.bmp pal8.png
+
+# BMP: bihsize=40, 127 x 32, bpp=8, compression=0, colors=252
+# "An image with non-square pixels: the X pixels/meter is twice the Y
+# pixels/meter. Image editors can be expected to leave the image 'squashed';
+# image viewers should consider stretching it to its correct proportions."
+# [We leave it squashed, as does Chromium.]
+fuzzy(0-1,0-1462) == pal8nonsquare.bmp pal8nonsquare-e.png
+
+# BMP: bihsize=12, 127 x 64, bpp=8, compression=0, colors=0
+# "An OS/2-style bitmap."
+fuzzy(0-1,0-996) == pal8os2.bmp pal8.png
+
+# BMP: bihsize=108, 127 x 64, bpp=8, compression=0, colors=252
+# "A v4 bitmap. I’m not sure that the gamma and chromaticity values in this
+# file are sensible, because I can’t find any detailed documentation of them."
+# [We seem to handle the profile wrong in QCMS. See bug 1619332.]
+fuzzy-if((/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&/^aarch64-msvc/.test(xulRuntime.XPCOMABI)),1-4,899-6376) fuzzy-if(!(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&/^aarch64-msvc/.test(xulRuntime.XPCOMABI)),3-3,6376-6376) fuzzy-if(appleSilicon,4-4,6376-6376) == pal8v4.bmp pal8.png #bug 1619847
+
+# BMP: bihsize=124, 127 x 64, bpp=8, compression=0, colors=252
+# "A v5 bitmap. Version 5 has additional colorspace options over v4, so it is
+# easier to create, and ought to be more portable."
+fuzzy(0-1,0-996) == pal8v5.bmp pal8.png
+
+# BMP: bihsize=40, 127 x 64, bpp=16, compression=0, colors=0
+# "A 16-bit image with the default color format: 5 bits each for red, green, and
+# blue, and 1 unused bit. The whitest colors should (I assume) be displayed as
+# pure white: (255,255,255), not (248,248,248)."
+fuzzy(0-1,0-1296) == rgb16.bmp rgb16.png
+
+# BMP: bihsize=40, 127 x 64, bpp=16, compression=3, colors=0
+# "Same format as rgb16.bmp, but with a BITFIELDS segment."
+fuzzy(0-1,0-1296) == rgb16bfdef.bmp rgb16.png
+
+# BMP: bihsize=40, 127 x 64, bpp=16, compression=3, colors=0
+# "A 16-bit image with a BITFIELDS segment indicating 5 red, 6 green, and 5 blue
+# bits. This is a standard 16-bit format, even supported by old versions of
+# Windows that don’t support any other non-default 16-bit formats. The whitest
+# colors should be displayed as pure white: (255,255,255), not (248,252,248)."
+fuzzy(0-1,0-1296) == rgb16.bmp rgb16.png
+
+# BMP: bihsize=40, 127 x 64, bpp=16, compression=3, colors=256
+# "A 16-bit image with both a BITFIELDS segment and a palette."
+fuzzy(0-1,0-1516) == rgb16.bmp rgb16.png
+
+# BMP: bihsize=40, 127 x 64, bpp=24, compression=0, colors=0
+# "A perfectly ordinary 24-bit (truecolor) image."
+== rgb24.bmp rgb24.png
+
+# BMP: bihsize=40, 127 x 64, bpp=24, compression=0, colors=256
+# "A 24-bit image, with a palette containing 256 colors. There is little if any
+# reason for a truecolor image to contain a palette, but it is legal."
+== rgb24pal.bmp rgb24.png
+
+# BMP: bihsize=40, 127 x 64, bpp=32, compression=0, colors=0
+# "A 32-bit image using the default color format for 32-bit images (no
+# BITFIELDS segment). There are 8 bits per color channel, and 8 unused bits.
+# The unused bits are set to 0."
+== rgb32.bmp rgb24.png
+
+# BMP: bihsize=40, 127 x 64, bpp=32, compression=3, colors=0
+# "Same format as rgb32.bmp, but with a BITFIELDS segment."
+== rgb32bfdef.bmp rgb24.png
+
+# BMP: bihsize=40, 127 x 64, bpp=32, compression=3, colors=0
+# "A 32-bit image with a BITFIELDS segment. As usual, there are 8 bits per color
+# channel, and 8 unused bits. But the color channels are in an unusual order,
+# so the viewer must read the BITFIELDS, and not just guess."
+== rgb32bf.bmp rgb24.png
+
diff --git a/image/test/reftest/bmp/bmpsuite/g/rgb16-565.bmp b/image/test/reftest/bmp/bmpsuite/g/rgb16-565.bmp
new file mode 100644
index 0000000000..c03a27975a
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/rgb16-565.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/rgb16-565.png b/image/test/reftest/bmp/bmpsuite/g/rgb16-565.png
new file mode 100644
index 0000000000..04a3121d24
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/rgb16-565.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/rgb16-565pal.bmp b/image/test/reftest/bmp/bmpsuite/g/rgb16-565pal.bmp
new file mode 100644
index 0000000000..e7632e344b
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/rgb16-565pal.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/rgb16.bmp b/image/test/reftest/bmp/bmpsuite/g/rgb16.bmp
new file mode 100644
index 0000000000..6bfe47af4f
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/rgb16.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/rgb16.png b/image/test/reftest/bmp/bmpsuite/g/rgb16.png
new file mode 100644
index 0000000000..d9545840ab
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/rgb16.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/rgb16bfdef.bmp b/image/test/reftest/bmp/bmpsuite/g/rgb16bfdef.bmp
new file mode 100644
index 0000000000..30fe8bb8d6
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/rgb16bfdef.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/rgb24.bmp b/image/test/reftest/bmp/bmpsuite/g/rgb24.bmp
new file mode 100644
index 0000000000..40f8bb094b
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/rgb24.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/rgb24.png b/image/test/reftest/bmp/bmpsuite/g/rgb24.png
new file mode 100644
index 0000000000..86a9c945b0
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/rgb24.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/rgb24pal.bmp b/image/test/reftest/bmp/bmpsuite/g/rgb24pal.bmp
new file mode 100644
index 0000000000..102e971dd3
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/rgb24pal.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/rgb32.bmp b/image/test/reftest/bmp/bmpsuite/g/rgb32.bmp
new file mode 100644
index 0000000000..5d57eaaea8
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/rgb32.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/rgb32bf.bmp b/image/test/reftest/bmp/bmpsuite/g/rgb32bf.bmp
new file mode 100644
index 0000000000..20fa9a1326
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/rgb32bf.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/g/rgb32bfdef.bmp b/image/test/reftest/bmp/bmpsuite/g/rgb32bfdef.bmp
new file mode 100644
index 0000000000..d7e64e5a41
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/g/rgb32bfdef.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal1huff.bmp b/image/test/reftest/bmp/bmpsuite/q/pal1huff.bmp
new file mode 100644
index 0000000000..790a483697
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal1huff.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal1p1.bmp b/image/test/reftest/bmp/bmpsuite/q/pal1p1.bmp
new file mode 100644
index 0000000000..b68321c4c1
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal1p1.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal1p1.png b/image/test/reftest/bmp/bmpsuite/q/pal1p1.png
new file mode 100644
index 0000000000..92fc0f945b
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal1p1.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal2.bmp b/image/test/reftest/bmp/bmpsuite/q/pal2.bmp
new file mode 100644
index 0000000000..983e9fa92d
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal2.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal2color.bmp b/image/test/reftest/bmp/bmpsuite/q/pal2color.bmp
new file mode 100644
index 0000000000..27fe7276bc
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal2color.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal4rlecut.bmp b/image/test/reftest/bmp/bmpsuite/q/pal4rlecut.bmp
new file mode 100644
index 0000000000..2f32d1d7ad
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal4rlecut.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal4rlecut.png b/image/test/reftest/bmp/bmpsuite/q/pal4rlecut.png
new file mode 100644
index 0000000000..767f5a0ad7
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal4rlecut.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal4rletrns.bmp b/image/test/reftest/bmp/bmpsuite/q/pal4rletrns.bmp
new file mode 100644
index 0000000000..58994e92ba
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal4rletrns.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal4rletrns.png b/image/test/reftest/bmp/bmpsuite/q/pal4rletrns.png
new file mode 100644
index 0000000000..9b0c044364
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal4rletrns.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8.png b/image/test/reftest/bmp/bmpsuite/q/pal8.png
new file mode 100644
index 0000000000..2bfd3e650f
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8offs.bmp b/image/test/reftest/bmp/bmpsuite/q/pal8offs.bmp
new file mode 100644
index 0000000000..8673e9740b
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8offs.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8os2-hs.bmp b/image/test/reftest/bmp/bmpsuite/q/pal8os2-hs.bmp
new file mode 100644
index 0000000000..018a3c4b16
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8os2-hs.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8os2-sz.bmp b/image/test/reftest/bmp/bmpsuite/q/pal8os2-sz.bmp
new file mode 100644
index 0000000000..7f1455d5ef
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8os2-sz.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8os2sp.bmp b/image/test/reftest/bmp/bmpsuite/q/pal8os2sp.bmp
new file mode 100644
index 0000000000..e532c89863
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8os2sp.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8os2v2-16.bmp b/image/test/reftest/bmp/bmpsuite/q/pal8os2v2-16.bmp
new file mode 100644
index 0000000000..95a1d2345a
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8os2v2-16.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8os2v2-40sz.bmp b/image/test/reftest/bmp/bmpsuite/q/pal8os2v2-40sz.bmp
new file mode 100644
index 0000000000..d1e66b615c
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8os2v2-40sz.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8os2v2-sz.bmp b/image/test/reftest/bmp/bmpsuite/q/pal8os2v2-sz.bmp
new file mode 100644
index 0000000000..6fe566e3fd
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8os2v2-sz.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8os2v2.bmp b/image/test/reftest/bmp/bmpsuite/q/pal8os2v2.bmp
new file mode 100644
index 0000000000..1324a40d00
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8os2v2.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8oversizepal.bmp b/image/test/reftest/bmp/bmpsuite/q/pal8oversizepal.bmp
new file mode 100644
index 0000000000..93b8187ca1
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8oversizepal.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8rlecut.bmp b/image/test/reftest/bmp/bmpsuite/q/pal8rlecut.bmp
new file mode 100644
index 0000000000..840d31cce6
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8rlecut.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8rlecut.png b/image/test/reftest/bmp/bmpsuite/q/pal8rlecut.png
new file mode 100644
index 0000000000..dfceeb568b
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8rlecut.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8rletrns.bmp b/image/test/reftest/bmp/bmpsuite/q/pal8rletrns.bmp
new file mode 100644
index 0000000000..a2af88d87c
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8rletrns.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/pal8rletrns.png b/image/test/reftest/bmp/bmpsuite/q/pal8rletrns.png
new file mode 100644
index 0000000000..2d8e957f1f
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/pal8rletrns.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/reftest.list b/image/test/reftest/bmp/bmpsuite/q/reftest.list
new file mode 100644
index 0000000000..cead5df00b
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/reftest.list
@@ -0,0 +1,251 @@
+# bmpsuite "questionable" tests
+
+# See ../README.mozilla for details.
+
+# BMP: bihsize=40, 127 x 64, bpp=1, compression=0, colors=1
+# "1 bit/pixel paletted image, with only one color in the palette. The
+# documentation says that 1-bpp images have a palette size of 2 (not 'up to
+# 2'), but it would be silly for a viewer not to support a size of 1."
+# [We accept it. So does Chromium.]
+fuzzy(0-1,0-926) == pal1p1.bmp pal1p1.png
+
+# BMP: bihsize=64, 127 x 64, bpp=1, compression=3, colors=2
+# "My attempt to make a BMP file with Huffman 1D compression. It is quite
+# possibly incorrect. Even if everything else about it is correct, I have no
+# way to know whether it is black/white reversed."
+# [We reject it. So does Chromium.]
+== wrapper.html?pal1huff.bmp about:blank
+
+# BMP: bihsize=40, 127 x 64, bpp=2, compression=0, colors=4
+# "A paletted image with 2 bits/pixel. Usually only 1, 4, and 8 are allowed,
+# but 2 is legal on Windows CE."
+# [We reject it. Chromium accepts it.]
+== wrapper.html?pal2.bmp about:blank
+
+# BMP: bihsize=40, 127 x 64, bpp=2, compression=0, colors=4
+# "Same as pal2.bmp, but with a color palette instead of grayscale palette."
+# [We reject it. Chromium accepts it.]
+== wrapper.html?pal2color.bmp about:blank
+
+# BMP: bihsize=40, 127 x 64, bpp=4, compression=2, colors=13
+# "An RLE-compressed image that used 'delta' codes to skip over some pixels,
+# leaving them undefined. Some viewers make undefined pixels transparent,
+# others make them black, and others assign them palette color 0 (purple, in
+# this case)."
+# [We make the undefined pixels transparent. So does Chromium.]
+== pal4rletrns.bmp pal4rletrns.png
+
+# BMP: bihsize=40, 127 x 64, bpp=4, compression=2, colors=13
+# "An RLE-compressed image that uses “delta†codes, and early EOL & EOBMP
+# markers, to skip over some pixels."
+== pal4rlecut.bmp pal4rlecut.png
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=1, colors=253
+# "8-bit version of q/pal4rletrns.bmp."
+# [Ditto.]
+== pal8rletrns.bmp pal8rletrns.png
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=1, colors=253
+# "8-bit version of q/pal4rlecut.bmp."
+== pal8rlecut.bmp pal8rlecut.png
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=0, colors=252
+# "A file with some unused bytes between the palette and the image. This is
+# probably valid, but I’m not 100% sure."
+# [We accept it. So does Chromium.]
+fuzzy(0-1,0-996) == pal8offs.bmp pal8.png
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=0, colors=300
+# "An 8-bit image with 300 palette colors. This may be invalid, because the
+# documentation could be interpreted to imply that 8-bit images aren’t allowed
+# to have more than 256 colors."
+# [We accept it. So does Chromium.]
+fuzzy(0-1,0-996) == pal8oversizepal.bmp pal8.png
+
+# BMP: bihsize=12, 127 x 64, bpp=8, compression=0, colors=0
+# # "Some OS/2 BMP specifications say that the size field in the file header
+# should be set to the aggregate size of the file header and infoheader,
+# instead of the total file size. For OS/2v1, that means it will always be 26.
+# BMP decoders usually ignore this field, so it shouldn’t cause a problem."
+fuzzy(0-1,0-996) == pal8os2-sz.bmp pal8.png
+
+# BMP: bihsize=12, 127 x 64, bpp=8, compression=0, colors=0
+# "Some OS/2 BMP specifications define the fields at offsets 6 and 8 to be a
+# “hotspot†(for cursor graphics). Though the fields are not used in BMP files,
+# they are sometimes, as in this file, set to nonzero values. This should cause
+# no problems, except that it could prevent some programs from detecting this
+# file as a BMP file."
+fuzzy(0-1,0-996) == pal8os2-hs.bmp pal8.png
+
+# BMP: bihsize=12, 127 x 64, bpp=8, compression=0, colors=0
+# "An OS/2v1 with a less-than-full-sized palette. Probably not valid, but such
+# files have been seen in the wild."
+# [We reject it. Chromium accepts it.]
+fuzzy(0-245,0-8128) == wrapper.html?pal8os2sp.bmp about:blank
+
+# BMP: bihsize=64, 127 x 64, bpp=8, compression=0, colors=252
+# "My attempt to make an OS/2v2 bitmap."
+# [We accept it. So does Chromium.]
+fuzzy(0-1,0-996) == pal8os2v2.bmp pal8.png
+
+# BMP: bihsize=16, 127 x 64, bpp=8, compression=0, colors=0
+# "An OS/2v2 bitmap whose header has only 16 bytes, instead of the full 64."
+# [We accept it. So does Chromium.]
+fuzzy(0-1,0-996) == pal8os2v2-16.bmp pal8.png
+
+# BMP: bihsize=64, 127 x 64, bpp=8, compression=0, colors=252
+# "An OS/2v2 bitmap. Like q/pal8os2-sz.bmp, the size field is set to the size
+# of the headers (78), instead of the size of the file."
+fuzzy(0-1,0-996) == pal8os2v2-sz.bmp pal8.png
+
+# BMP: bihsize=40, 127 x 64, bpp=8, compression=0, colors=252
+# "An OS/2v2 bitmap, with a 40-byte header. Like q/pal8os2-sz.bmp, the size
+# field is set to the size of the headers (54), instead of the size of the
+# file. Except for that, this file cannot be distinguished from a Windows
+# BMPv3 file."
+fuzzy(0-1,0-996) == pal8os2v2-40sz.bmp pal8.png
+
+# BMP: bihsize=40, 127 x 64, bpp=16, compression=0, colors=0
+# "Same idea as q/rgb32fakealpha.bmp. The default 16-bit color format has one
+# unused bit per pixel, and in this image some of the unused bits are set to 1.
+# It’s possible that some viewers will interpret this image as having
+# transparency."
+fuzzy(0-1,0-1296) == rgb16faketrns.bmp rgb16.png
+
+# BMP: bihsize=40, 127 x 64, bpp=16, compression=3, colors=0
+# "An unusual and silly 16-bit image, with 2 red bits, 3 green bits, and 1 blue
+# bit. Most viewers do support this image, but the colors may be darkened with
+# a yellow-green shadow. That’s because they’re doing simple bit-shifting
+# (possibly including one round of bit replication), instead of proper
+# scaling."
+== rgb16-231.bmp rgb16-231.png
+
+# BMP: bihsize=40, 127 x 64, bpp=16, compression=3, colors=0
+# "Similar to q/rgb16-231.bmp, with 3 red bits, 10 green bits, and 3 blue
+# bits."
+fuzzy(0-1,0-689) == rgb16-3103.bmp rgb16-3103.png
+
+# BMP: bihsize=124, 127 x 64, bpp=16, compression=3, colors=0
+# "A 16-bit image with an alpha channel. There are 4 bits for each color
+# channel, and 4 bits for the alpha channel. It’s not clear if this is valid,
+# but I can’t find anything that suggests it isn’t."
+== rgba16-4444.bmp rgba16-4444.png
+
+# BMP: bihsize=124, 127 x 64, bpp=16, compression=3, colors=0
+# "Similar to q/rgba16-4444.bmp, with 5 red bits, 5 green bits, 5 blue bits,
+# and a 1-bit alpha channel."
+fuzzy(0-1,0-2203) == rgba16-5551.bmp rgba16-5551.png
+
+# BMP: bihsize=124, 127 x 64, bpp=16, compression=3, colors=0
+# "Similar to q/rgba16-4444.bmp, with 1 red bit, 9 green bits, 2 blue bits,
+# and 4 bits for the alpha channel."
+== rgba16-1924.bmp rgba16-1924.png
+
+# BMP: bihsize=40, 127 x 64, bpp=24, compression=0, colors=300
+# "A 24-bit image, with a palette containing 300 colors. The fact that the
+# palette has more than 256 colors may cause some viewers to complain, but the
+# documentation does not mention a size limit."
+# [We accept it. So does Chromium.]
+== rgb24largepal.bmp rgb24.png
+
+# BMP: bihsize=124, 127 x 64, bpp=24, compression=0, colors=0
+# "My attempt to make a BMP file with an embedded color profile."
+fuzzy(1-1,28-73) == rgb24prof.bmp rgb24.png
+
+# BMP: bihsize=124, 127 x 64, bpp=24, compression=0, colors=0
+# "This image tries to test whether color profiles are fully supported. It has
+# the red and green channels swapped, and an embedded color profile that tries
+# to swap them back. Support for this is uncommon."
+# [The image is significantly closer to the desired output than without color
+# management, but we seem to handle the profile wrong in QCMS. See bug 1619332.]
+fuzzy(10-10,6590-6597) == rgb24prof2.bmp rgb24.png
+
+# BMP: bihsize=124, 127 x 64, bpp=24, compression=0, colors=0
+# "My attempt to make a BMP file with a linked color profile."
+# [We accept it, though we don't do anything with the color profile. Chromium
+# also handles it.]
+== rgb24lprof.bmp rgb24.png
+
+# BMP: bihsize=124, 127 x 64, bpp=0, compression=4, colors=0
+# BMP: bihsize=124, 127 x 64, bpp=0, compression=5, colors=0
+# "My attempt to make BMP files with embedded JPEG and PNG images. These are
+# not likely to be supported by much of anything (they’re intended for
+# printers)."
+# [We reject them. Chromium accepts them.]
+== wrapper.html?rgb24jpeg.bmp about:blank
+== wrapper.html?rgb24png.bmp about:blank
+
+# BMP: bihsize=64, 127 x 64, bpp=24, compression=4, colors=0
+# "An OS/2v2 bitmap with RLE24 compression. This image uses a limited number
+# of colors, just to make it more compressible."
+# [We reject it. Chromium accepts it.]
+== wrapper.html?rgb24rle24.bmp about:blank
+
+# BMP: bihsize=52, 127 x 64, bpp=32, compression=3, colors=0
+# "Similar to g/rgb32bf.bmp, but with a 52-byte “BITMAPV2INFOHEADERâ€. This is
+# an uncommon version of BMP, and I can’t confirm that this file is correct."
+# [We reject it. Chromium accepts it.]
+== wrapper.html?rgb32h52.bmp about:blank
+
+# BMP: bihsize=124, 127 x 64, bpp=32, compression=3, colors=0
+# "Color channels are the same size and order as rgb32bfdef.bmp, but they use
+# the highest available bits, instead of the lowest (or vice versa, depending
+# on your byte-order perspective)."
+== rgb32-xbgr.bmp rgb24.png
+
+# BMP: bihsize=40, 127 x 64, bpp=32, compression=0, colors=0
+# "Same as g/rgb32.bmp, except that the unused bits are set to something other
+# than 0. If the image becomes transparent toward the bottom, it probably means
+# the viewer uses heuristics to guess whether the undefined data represents
+# transparency."
+# [We don't apply transparency here. Chromium does the same.]
+== rgb32fakealpha.bmp rgb24.png
+
+# BMP: bihsize=40, 127 x 64, bpp=32, compression=3, colors=0
+# "A 32 bits/pixel image, with all 32 bits used: 11 each for red and green, and
+# 10 for blue. As far as I know, this is perfectly valid, but it is unusual."
+fuzzy(0-1,0-1408) == rgb32-111110.bmp rgb24.png
+
+# BMP: bihsize=40, 127 x 64, bpp=32, compression=3, colors=0
+# "A 32 bits/pixel image, with 7 bits for red, 18 for green, and 7 for blue."
+fuzzy(0-1,0-753) == rgb32-7187.bmp rgb32-7187.png
+
+# BMP: bihsize=124, 127 x 64, bpp=32, compression=3, colors=0
+# "A BMP with an alpha channel. Transparency is barely documented, so it’s
+# possible that this file is not correctly formed. The color channels are in an
+# unusual order, to prevent viewers from passing this test by making a lucky
+# guess."
+== rgba32-1.bmp rgba32.png
+
+# BMP: bihsize=124, 127 x 64, bpp=32, compression=3, colors=0
+# "Same as rgba32-1.bmp, but with the color channels in an unusual order, to
+# prevent viewers from passing this test by making a lucky guess."
+== rgba32-2.bmp rgba32.png
+
+# BMP: bihsize=124, 127 x 64, bpp=32, compression=3, colors=0
+# "A 32 bits/pixel image, with 10 bits for red, 10 for green, 10 for blue, and
+# 2 for alpha."
+fuzzy(0-1,0-1296) == rgba32-1010102.bmp rgba32-1010102.png
+
+# BMP: bihsize=124, 127 x 64, bpp=32, compression=3, colors=0
+# "A 32 bits/pixel image, with 8 bits for red, 12 for green, 8 for blue, and 4
+# for alpha."
+fuzzy(0-1,0-753) == rgba32-81284.bmp rgba32-81284.png
+
+# BMP: bihsize=124, 127 x 64, bpp=32, compression=3, colors=0
+# "A 32 bits/pixel image, with 6 bits for red, 17 for green, 5 for blue, and 4
+# for alpha."
+fuzzy(0-1,0-1554) == rgba32-61754.bmp rgba32-61754.png
+
+# BMP: bihsize=40, 127 x 64, bpp=32, compression=6, colors=0
+# "An image of type BI_ALPHABITFIELDS. Supposedly, this was used on Windows CE.
+# I don’t know whether it is constructed correctly."
+# [We reject it. Chromium accepts it.]
+== wrapper.html?rgba32abf.bmp about:blank
+
+# BMP: bihsize=56, 127 x 64, bpp=32, compression=3, colors=0
+# "Similar to q/rgba32.bmp, but with a 56-byte “BITMAPV3INFOHEADERâ€. This is an
+# uncommon version of BMP, and I can’t confirm that this file is correct."
+# [We reject it. Chromium accepts it.]
+== wrapper.html?rgba32h56.bmp about:blank
+
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb16-231.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb16-231.bmp
new file mode 100644
index 0000000000..6300f69f0c
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb16-231.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb16-231.png b/image/test/reftest/bmp/bmpsuite/q/rgb16-231.png
new file mode 100644
index 0000000000..76efe526e5
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb16-231.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb16-3103.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb16-3103.bmp
new file mode 100644
index 0000000000..6e01226029
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb16-3103.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb16-3103.png b/image/test/reftest/bmp/bmpsuite/q/rgb16-3103.png
new file mode 100644
index 0000000000..79ba23c834
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb16-3103.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb16.png b/image/test/reftest/bmp/bmpsuite/q/rgb16.png
new file mode 100644
index 0000000000..d9545840ab
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb16.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb16faketrns.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb16faketrns.bmp
new file mode 100644
index 0000000000..62fb393bb9
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb16faketrns.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb24.png b/image/test/reftest/bmp/bmpsuite/q/rgb24.png
new file mode 100644
index 0000000000..86a9c945b0
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb24.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb24jpeg.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb24jpeg.bmp
new file mode 100644
index 0000000000..87d73d75b8
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb24jpeg.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb24largepal.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb24largepal.bmp
new file mode 100644
index 0000000000..d5e418c2d4
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb24largepal.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb24lprof.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb24lprof.bmp
new file mode 100644
index 0000000000..b868b88f20
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb24lprof.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb24png.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb24png.bmp
new file mode 100644
index 0000000000..e87ec7adda
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb24png.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb24prof.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb24prof.bmp
new file mode 100644
index 0000000000..627e676eae
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb24prof.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb24prof2.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb24prof2.bmp
new file mode 100644
index 0000000000..f9f61b8ee3
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb24prof2.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb24rle24.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb24rle24.bmp
new file mode 100644
index 0000000000..360aee649c
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb24rle24.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb32-111110.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb32-111110.bmp
new file mode 100644
index 0000000000..ec07d89b5b
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb32-111110.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb32-7187.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb32-7187.bmp
new file mode 100644
index 0000000000..887ba52c91
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb32-7187.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb32-7187.png b/image/test/reftest/bmp/bmpsuite/q/rgb32-7187.png
new file mode 100644
index 0000000000..a1da44d6be
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb32-7187.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb32-xbgr.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb32-xbgr.bmp
new file mode 100644
index 0000000000..c6c05e1480
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb32-xbgr.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb32fakealpha.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb32fakealpha.bmp
new file mode 100644
index 0000000000..cb544da5b6
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb32fakealpha.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgb32h52.bmp b/image/test/reftest/bmp/bmpsuite/q/rgb32h52.bmp
new file mode 100644
index 0000000000..db6e4538ef
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgb32h52.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba16-1924.bmp b/image/test/reftest/bmp/bmpsuite/q/rgba16-1924.bmp
new file mode 100644
index 0000000000..6564098a4d
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba16-1924.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba16-1924.png b/image/test/reftest/bmp/bmpsuite/q/rgba16-1924.png
new file mode 100644
index 0000000000..0fc182f153
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba16-1924.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba16-4444.bmp b/image/test/reftest/bmp/bmpsuite/q/rgba16-4444.bmp
new file mode 100644
index 0000000000..051ff23589
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba16-4444.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba16-4444.png b/image/test/reftest/bmp/bmpsuite/q/rgba16-4444.png
new file mode 100644
index 0000000000..bfeda6faed
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba16-4444.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba16-5551.bmp b/image/test/reftest/bmp/bmpsuite/q/rgba16-5551.bmp
new file mode 100644
index 0000000000..73e2cd533f
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba16-5551.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba16-5551.png b/image/test/reftest/bmp/bmpsuite/q/rgba16-5551.png
new file mode 100644
index 0000000000..613126a8ab
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba16-5551.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba32-1.bmp b/image/test/reftest/bmp/bmpsuite/q/rgba32-1.bmp
new file mode 100644
index 0000000000..3c1e2648fc
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba32-1.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba32-1010102.bmp b/image/test/reftest/bmp/bmpsuite/q/rgba32-1010102.bmp
new file mode 100644
index 0000000000..1a918cebf5
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba32-1010102.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba32-1010102.png b/image/test/reftest/bmp/bmpsuite/q/rgba32-1010102.png
new file mode 100644
index 0000000000..a472fbc799
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba32-1010102.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba32-2.bmp b/image/test/reftest/bmp/bmpsuite/q/rgba32-2.bmp
new file mode 100644
index 0000000000..829c7c7e34
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba32-2.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba32-61754.bmp b/image/test/reftest/bmp/bmpsuite/q/rgba32-61754.bmp
new file mode 100644
index 0000000000..d5936fd20b
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba32-61754.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba32-61754.png b/image/test/reftest/bmp/bmpsuite/q/rgba32-61754.png
new file mode 100644
index 0000000000..c593b14c66
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba32-61754.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba32-81284.bmp b/image/test/reftest/bmp/bmpsuite/q/rgba32-81284.bmp
new file mode 100644
index 0000000000..1f9fc29d6b
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba32-81284.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba32-81284.png b/image/test/reftest/bmp/bmpsuite/q/rgba32-81284.png
new file mode 100644
index 0000000000..c958cd36fc
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba32-81284.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba32.png b/image/test/reftest/bmp/bmpsuite/q/rgba32.png
new file mode 100644
index 0000000000..25e542a655
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba32.png
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba32abf.bmp b/image/test/reftest/bmp/bmpsuite/q/rgba32abf.bmp
new file mode 100644
index 0000000000..d9bb0189c4
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba32abf.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/rgba32h56.bmp b/image/test/reftest/bmp/bmpsuite/q/rgba32h56.bmp
new file mode 100644
index 0000000000..343baa3300
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/rgba32h56.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/q/wrapper.html b/image/test/reftest/bmp/bmpsuite/q/wrapper.html
new file mode 100644
index 0000000000..22b74c8fc1
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/q/wrapper.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Image reftest wrapper</title>
+<style type="text/css">
+ #image1 { background-color: rgb(10, 100, 250); }
+</style>
+<script>
+ // The image is loaded async after the page loads
+ // wait for it to finish loading
+ function onImageLoad() {
+ document.documentElement.removeAttribute("class");
+ };
+</script>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img id="image1" alt=" ">
+<script>
+ // Use as "wrapper.html?image.png"
+ var imgURL = document.location.search.substr(1);
+ document.images[0].onload = onImageLoad;
+ document.images[0].onerror = onImageLoad;
+ document.images[0].src = imgURL;
+</script>
+</body>
+</html>
+
diff --git a/image/test/reftest/bmp/bmpsuite/reftest.list b/image/test/reftest/bmp/bmpsuite/reftest.list
new file mode 100644
index 0000000000..532ea5ed93
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/reftest.list
@@ -0,0 +1,8 @@
+# bmpsuite tests
+
+# See README.mozilla for details about these tests.
+
+include g/reftest.list
+include q/reftest.list
+include b/reftest.list
+include x/reftest.list
diff --git a/image/test/reftest/bmp/bmpsuite/x/ba-bm.bmp b/image/test/reftest/bmp/bmpsuite/x/ba-bm.bmp
new file mode 100644
index 0000000000..d2615bde3e
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/x/ba-bm.bmp
Binary files differ
diff --git a/image/test/reftest/bmp/bmpsuite/x/reftest.list b/image/test/reftest/bmp/bmpsuite/x/reftest.list
new file mode 100644
index 0000000000..3c93479292
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/x/reftest.list
@@ -0,0 +1,10 @@
+# bmpsuite 'files in formats related to BMP, that you might not consider to
+# truly be in "BMP format"' tests
+
+# See ../README.mozilla for details.
+
+# "This image uses the OS/2v2 “Bitmap Array†(BA) container format. Although a
+# BA file may contain multiple images, this file has only one."
+== wrapper.html?ba-bm.bmp about:blank
+
+
diff --git a/image/test/reftest/bmp/bmpsuite/x/wrapper.html b/image/test/reftest/bmp/bmpsuite/x/wrapper.html
new file mode 100644
index 0000000000..f6c3ade538
--- /dev/null
+++ b/image/test/reftest/bmp/bmpsuite/x/wrapper.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Image reftest wrapper</title>
+<style type="text/css">
+ #image1 { background-color: rgb(10, 100, 250); }
+</style>
+<script>
+ // The image is loaded async after the page loads
+ // wait for it to finish loading
+ function onImageLoad() {
+ document.documentElement.removeAttribute("class");
+ };
+</script>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img id="image1" alt=" ">
+<script>
+ // Use as "wrapper.html?image.png"
+ var imgURL = document.location.search.substr(1);
+ document.images[0].onload = onImageLoad;
+ document.images[0].onerror = onImageLoad;
+ document.images[0].src = imgURL;
+</script>
+</body>
+</html>
+
diff --git a/image/test/reftest/bmp/reftest.list b/image/test/reftest/bmp/reftest.list
new file mode 100644
index 0000000000..87183e6b2f
--- /dev/null
+++ b/image/test/reftest/bmp/reftest.list
@@ -0,0 +1,16 @@
+# BMP tests
+
+include bmp-1bpp/reftest.list
+include bmp-4bpp/reftest.list
+include bmp-8bpp/reftest.list
+include bmp-24bpp/reftest.list
+include bmp-corrupted/reftest.list
+include bmpsuite/reftest.list
+
+# Two bmp files where the offset to the start of the image data in the file
+# is past the end of the file. In 1240629-1.bmp the offset us uint32_max,
+# so we are testing that we don't try to allocate a buffer that size (and
+# fail on 32 bit platforms) and declare the image in error state. If in the
+# future we decide that such bmps (offset past the end of the file) are
+# invalid the test will still pass, but won't be testing much.
+== 1240629-1.bmp 1240629-2.bmp
diff --git a/image/test/reftest/color-management/color-curv.png b/image/test/reftest/color-management/color-curv.png
new file mode 100644
index 0000000000..994e3a38a6
--- /dev/null
+++ b/image/test/reftest/color-management/color-curv.png
Binary files differ
diff --git a/image/test/reftest/color-management/color-lin.png b/image/test/reftest/color-management/color-lin.png
new file mode 100644
index 0000000000..0ee276fca3
--- /dev/null
+++ b/image/test/reftest/color-management/color-lin.png
Binary files differ
diff --git a/image/test/reftest/color-management/color-table.png b/image/test/reftest/color-management/color-table.png
new file mode 100644
index 0000000000..355b3a2ba6
--- /dev/null
+++ b/image/test/reftest/color-management/color-table.png
Binary files differ
diff --git a/image/test/reftest/color-management/invalid-chrm-ref.png b/image/test/reftest/color-management/invalid-chrm-ref.png
new file mode 100644
index 0000000000..85f83f7834
--- /dev/null
+++ b/image/test/reftest/color-management/invalid-chrm-ref.png
Binary files differ
diff --git a/image/test/reftest/color-management/invalid-chrm.png b/image/test/reftest/color-management/invalid-chrm.png
new file mode 100644
index 0000000000..33dc9e9ce0
--- /dev/null
+++ b/image/test/reftest/color-management/invalid-chrm.png
Binary files differ
diff --git a/image/test/reftest/color-management/invalid-whitepoint.png b/image/test/reftest/color-management/invalid-whitepoint.png
new file mode 100644
index 0000000000..383a0a035f
--- /dev/null
+++ b/image/test/reftest/color-management/invalid-whitepoint.png
Binary files differ
diff --git a/image/test/reftest/color-management/reftest.list b/image/test/reftest/color-management/reftest.list
new file mode 100644
index 0000000000..a99b4d4391
--- /dev/null
+++ b/image/test/reftest/color-management/reftest.list
@@ -0,0 +1,7 @@
+# Colormangement
+
+# test for bug 489133, test for bug 460520
+== invalid-chrm.png invalid-chrm-ref.png
+== invalid-whitepoint.png invalid-chrm-ref.png
+# test for bug 488955
+== trc-type.html trc-type-ref.html # Bug 1560617
diff --git a/image/test/reftest/color-management/trc-type-ref.html b/image/test/reftest/color-management/trc-type-ref.html
new file mode 100644
index 0000000000..5140e6e6af
--- /dev/null
+++ b/image/test/reftest/color-management/trc-type-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<body>
+ <img src="color-lin.png">
+ <img src="color-curv.png">
+ <img src="color-table.png">
+</body>
+</html>
diff --git a/image/test/reftest/color-management/trc-type.html b/image/test/reftest/color-management/trc-type.html
new file mode 100644
index 0000000000..f13052bbf4
--- /dev/null
+++ b/image/test/reftest/color-management/trc-type.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<body>
+ <!-- All of these images should render the same
+ they all have icc profiles with different
+ but equivalent tone reproduction curves.
+
+ The profiles were generated with the following code and added to the images using pngcrush.
+
+ cmsHPROFILE profile = cmsCreate_sRGBProfile();
+
+ cmsAddTag(profile, icSigDeviceMfgDescTag, (LPVOID) "(lcms moz internal)");
+ cmsAddTag(profile, icSigDeviceModelDescTag, (LPVOID) "linear");
+ cmsAddTag(profile, icSigProfileDescriptionTag, (LPVOID) "linear");
+
+ GAMMATABLE linear_trc;
+ linear_trc.nEntries = 0;
+
+ cmsAddTag(profile, icSigRedTRCTag, &linear_trc);
+ cmsAddTag(profile, icSigGreenTRCTag, &linear_trc);
+ cmsAddTag(profile, icSigBlueTRCTag, &linear_trc);
+
+ _cmsSaveProfile(profile, "linear_gen.icc");
+
+ GAMMATABLE linear_curve_trc;
+ linear_curve_trc.nEntries = 1;
+ linear_curve_trc.GammaTable[0] = 0x0100;
+
+ cmsAddTag(profile, icSigRedTRCTag, &linear_curve_trc);
+ cmsAddTag(profile, icSigGreenTRCTag, &linear_curve_trc);
+ cmsAddTag(profile, icSigBlueTRCTag, &linear_curve_trc);
+
+ _cmsSaveProfile(profile, "linear_curve_gen.icc");
+
+ GAMMATABLE *linear_table_trc = malloc(sizeof(GAMMATABLE) + sizeof(short)*2);
+ linear_table_trc->nEntries = 2;
+ linear_table_trc->GammaTable[0] = 0x0;
+ linear_table_trc->GammaTable[1] = 0xffff;
+
+ cmsAddTag(profile, icSigRedTRCTag, linear_table_trc);
+ cmsAddTag(profile, icSigGreenTRCTag, linear_table_trc);
+ cmsAddTag(profile, icSigBlueTRCTag, linear_table_trc);
+
+ _cmsSaveProfile(profile, "linear_table_gen.icc");
+
+ free(linear_table_trc);
+
+ -->
+ <img src="color-curv.png">
+ <img src="color-table.png">
+ <img src="color-lin.png">
+</body>
+</html>
diff --git a/image/test/reftest/colordepth.html b/image/test/reftest/colordepth.html
new file mode 100644
index 0000000000..15d2c9f95f
--- /dev/null
+++ b/image/test/reftest/colordepth.html
@@ -0,0 +1,16 @@
+<script>
+/*
+ * Almost all of the image decoding reftests require the display to be in
+ * 24-bit color mode, or else the rendered images will have subtle color
+ * variations and will fail.
+ * The Windows test boxes used to have a tendency to flip to 16-bit color mode,
+ * so this test will explicitly check the color depth to make it more obvious
+ * when the requirement is not met. (See bug 414720.)
+ * 24-bit is only a minimum, allow higher values too. (See bug 458847.)
+ */
+
+var colorDepth = window.screen.colorDepth;
+
+if (colorDepth < 24)
+ document.write("ERROR: color depth is only " + colorDepth + ".");
+</script>
diff --git a/image/test/reftest/downscaling/100x100.gif b/image/test/reftest/downscaling/100x100.gif
new file mode 100644
index 0000000000..4ff770d368
--- /dev/null
+++ b/image/test/reftest/downscaling/100x100.gif
Binary files differ
diff --git a/image/test/reftest/downscaling/100x100.jpg b/image/test/reftest/downscaling/100x100.jpg
new file mode 100644
index 0000000000..cea2c240d8
--- /dev/null
+++ b/image/test/reftest/downscaling/100x100.jpg
Binary files differ
diff --git a/image/test/reftest/downscaling/100x100.png b/image/test/reftest/downscaling/100x100.png
new file mode 100644
index 0000000000..eb3cb08e1e
--- /dev/null
+++ b/image/test/reftest/downscaling/100x100.png
Binary files differ
diff --git a/image/test/reftest/downscaling/100x32768.gif b/image/test/reftest/downscaling/100x32768.gif
new file mode 100644
index 0000000000..f55a2f482f
--- /dev/null
+++ b/image/test/reftest/downscaling/100x32768.gif
Binary files differ
diff --git a/image/test/reftest/downscaling/100x32768.jpg b/image/test/reftest/downscaling/100x32768.jpg
new file mode 100644
index 0000000000..e89acc0334
--- /dev/null
+++ b/image/test/reftest/downscaling/100x32768.jpg
Binary files differ
diff --git a/image/test/reftest/downscaling/100x32768.png b/image/test/reftest/downscaling/100x32768.png
new file mode 100644
index 0000000000..7cd5509cf2
--- /dev/null
+++ b/image/test/reftest/downscaling/100x32768.png
Binary files differ
diff --git a/image/test/reftest/downscaling/1404366-1.html b/image/test/reftest/downscaling/1404366-1.html
new file mode 100644
index 0000000000..165cc7f934
--- /dev/null
+++ b/image/test/reftest/downscaling/1404366-1.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<body>
+<!--
+ 1404366-1.ico is an ico file that contains a 32x32 0RGB (0 for all alpha values) bmp
+ where the color values are all white. It also contains a mask. The mask alternates
+ one pixel fully transparent, one pixel fully opaque. The result of drawing this on
+ a white background should be white. This is testing that we premultiply the color
+ values by the alpha derived from the mark when downscaling. If we do not skia will
+ get confused and likely draw non white pixels.
+-->
+<img src="1404366-1.ico" style="width: 12px; height: 12px;">
+</body>
+</html> \ No newline at end of file
diff --git a/image/test/reftest/downscaling/1404366-1.ico b/image/test/reftest/downscaling/1404366-1.ico
new file mode 100644
index 0000000000..51c020b069
--- /dev/null
+++ b/image/test/reftest/downscaling/1404366-1.ico
Binary files differ
diff --git a/image/test/reftest/downscaling/1421191-1.html b/image/test/reftest/downscaling/1421191-1.html
new file mode 100644
index 0000000000..b8146a2371
--- /dev/null
+++ b/image/test/reftest/downscaling/1421191-1.html
@@ -0,0 +1,20 @@
+<html reftest-zoom="1.6">
+<head>
+<style>
+#xx {
+background-image: url("1421191-1.png");
+background-position: -61px -797px;
+background-position-x: -61px;
+background-position-y: -797px;
+background-repeat: no-repeat;
+background-size: 82px auto;
+display: block;
+height: 24px;
+width: 22px;
+}
+</style>
+</head>
+<body>
+<span id="xx"></span>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/1421191-1.png b/image/test/reftest/downscaling/1421191-1.png
new file mode 100644
index 0000000000..e9b756a79e
--- /dev/null
+++ b/image/test/reftest/downscaling/1421191-1.png
Binary files differ
diff --git a/image/test/reftest/downscaling/32768x100.gif b/image/test/reftest/downscaling/32768x100.gif
new file mode 100644
index 0000000000..2194d13efc
--- /dev/null
+++ b/image/test/reftest/downscaling/32768x100.gif
Binary files differ
diff --git a/image/test/reftest/downscaling/32768x100.jpg b/image/test/reftest/downscaling/32768x100.jpg
new file mode 100644
index 0000000000..807b9adb27
--- /dev/null
+++ b/image/test/reftest/downscaling/32768x100.jpg
Binary files differ
diff --git a/image/test/reftest/downscaling/32768x100.png b/image/test/reftest/downscaling/32768x100.png
new file mode 100644
index 0000000000..3fe4fe1ce5
--- /dev/null
+++ b/image/test/reftest/downscaling/32768x100.png
Binary files differ
diff --git a/image/test/reftest/downscaling/black-border-bottom.png b/image/test/reftest/downscaling/black-border-bottom.png
new file mode 100644
index 0000000000..efa7ce2dce
--- /dev/null
+++ b/image/test/reftest/downscaling/black-border-bottom.png
Binary files differ
diff --git a/image/test/reftest/downscaling/black-border-left.png b/image/test/reftest/downscaling/black-border-left.png
new file mode 100644
index 0000000000..11bc67e983
--- /dev/null
+++ b/image/test/reftest/downscaling/black-border-left.png
Binary files differ
diff --git a/image/test/reftest/downscaling/black-border-rect.svg b/image/test/reftest/downscaling/black-border-rect.svg
new file mode 100644
index 0000000000..0fa01a0a63
--- /dev/null
+++ b/image/test/reftest/downscaling/black-border-rect.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.5 -0.5 53 43" stroke="#000000">
+ <rect x="0" y="7" width="52" height="35" fill="#ffffff"/>
+</svg>
diff --git a/image/test/reftest/downscaling/black-border-right.png b/image/test/reftest/downscaling/black-border-right.png
new file mode 100644
index 0000000000..081c52d5bc
--- /dev/null
+++ b/image/test/reftest/downscaling/black-border-right.png
Binary files differ
diff --git a/image/test/reftest/downscaling/black-border-top.png b/image/test/reftest/downscaling/black-border-top.png
new file mode 100644
index 0000000000..fc6e69e02a
--- /dev/null
+++ b/image/test/reftest/downscaling/black-border-top.png
Binary files differ
diff --git a/image/test/reftest/downscaling/bmp-size-16x16-24bpp.png b/image/test/reftest/downscaling/bmp-size-16x16-24bpp.png
new file mode 100644
index 0000000000..c04869e728
--- /dev/null
+++ b/image/test/reftest/downscaling/bmp-size-16x16-24bpp.png
Binary files differ
diff --git a/image/test/reftest/downscaling/downscale-1-bigimage.png b/image/test/reftest/downscaling/downscale-1-bigimage.png
new file mode 100644
index 0000000000..5e018590c3
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-1-bigimage.png
Binary files differ
diff --git a/image/test/reftest/downscaling/downscale-1-ref.html b/image/test/reftest/downscaling/downscale-1-ref.html
new file mode 100644
index 0000000000..63ec56ef7c
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-1-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html>
+<body>
+ <img src="downscale-1-smallimage.png">
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-1-smallimage.png b/image/test/reftest/downscaling/downscale-1-smallimage.png
new file mode 100644
index 0000000000..588e6b78df
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-1-smallimage.png
Binary files differ
diff --git a/image/test/reftest/downscaling/downscale-1.html b/image/test/reftest/downscaling/downscale-1.html
new file mode 100644
index 0000000000..a9629ef855
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html class="reftest-wait">
+<head>
+ <script>
+ function snapshot() {
+ document.documentElement.removeAttribute('class');
+ }
+ </script>
+</head>
+<!-- NOTE: Using setTimeout to wait for high-quality downscaled version of
+ image to be ready, because there's nothing better we can do. If we fix
+ Bug 1006883, we can do away with this setTimeout.
+
+ For now, the setTimeout is just here to increase the likelihood that we
+ actually test the high-quality downscaled version of the image. If the
+ setTimeout happens to fire before the high-quality downscaled rendering is
+ ready, then this the test will pass without testing what it's trying to
+ test, which is fine as long as that's rare. -->
+<body onload="setTimeout(snapshot, 50)">
+ <img src="downscale-1-bigimage.png" style="height: 20px; width: 20px">
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-16px.html b/image/test/reftest/downscaling/downscale-16px.html
new file mode 100644
index 0000000000..06d6db2bf6
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-16px.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Image reftest wrapper</title>
+<style type="text/css">
+ #image1 { background-color: rgb(10, 250, 100); }
+</style>
+<script>
+ // The image is loaded async after the page loads.
+ // Wait for it to finish loading.
+ function onImageLoad() {
+ document.documentElement.removeAttribute("class");
+ };
+</script>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img width="16px" height="16px" id="image1" alt=" ">
+<script>
+ // Use as "wrapper.html?image.png"
+ var imgURL = document.location.search.substr(1);
+ document.images[0].onload = onImageLoad;
+ document.images[0].onerror = onImageLoad;
+ document.images[0].src = imgURL;
+</script>
+</body>
+</html>
+
diff --git a/image/test/reftest/downscaling/downscale-2a.html b/image/test/reftest/downscaling/downscale-2a.html
new file mode 100644
index 0000000000..fac11ccee5
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-2a.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html reftest-zoom="1.0" class="reftest-wait">
+<head>
+ <script>
+ function snapshot() {
+ document.documentElement.removeAttribute('class');
+ }
+ </script>
+</head>
+<!-- NOTE: Using setTimeout to wait for high-quality downscaled version of
+ image to be ready, because there's nothing better we can do. If we fix
+ Bug 1006883, we can do away with this setTimeout.
+
+ For now, the setTimeout is just here to increase the likelihood that we
+ actually test the high-quality downscaled version of the image. If the
+ setTimeout happens to fire before the high-quality downscaled rendering is
+ ready, then this the test will pass without testing what it's trying to
+ test, which is fine as long as that's rare. -->
+<body style="margin: 0px" onload="setTimeout(snapshot, 50)">
+ <script>
+ var args = location.search.substring(1).split(',');
+ var image = document.createElement('img');
+ image.width = args[0];
+ image.height = args[1];
+ image.src = 'black-border-' + args[2] + '.png';
+ document.body.appendChild(image);
+ </script>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-2b.html b/image/test/reftest/downscaling/downscale-2b.html
new file mode 100644
index 0000000000..af7ecbff33
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-2b.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html reftest-zoom="0.9" class="reftest-wait">
+<head>
+ <script>
+ function snapshot() {
+ document.documentElement.removeAttribute('class');
+ }
+ </script>
+</head>
+<!-- NOTE: Using setTimeout to wait for high-quality downscaled version of
+ image to be ready, because there's nothing better we can do. If we fix
+ Bug 1006883, we can do away with this setTimeout.
+
+ For now, the setTimeout is just here to increase the likelihood that we
+ actually test the high-quality downscaled version of the image. If the
+ setTimeout happens to fire before the high-quality downscaled rendering is
+ ready, then this the test will pass without testing what it's trying to
+ test, which is fine as long as that's rare. -->
+<body style="margin: 0px" onload="setTimeout(snapshot, 50)">
+ <script>
+ var args = location.search.substring(1).split(',');
+ var image = document.createElement('img');
+ image.width = args[0];
+ image.height = args[1];
+ image.src = 'black-border-' + args[2] + '.png';
+ document.body.appendChild(image);
+ </script>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-2c.html b/image/test/reftest/downscaling/downscale-2c.html
new file mode 100644
index 0000000000..18f70456b1
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-2c.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html reftest-zoom="0.8" class="reftest-wait">
+<head>
+ <script>
+ function snapshot() {
+ document.documentElement.removeAttribute('class');
+ }
+ </script>
+</head>
+<!-- NOTE: Using setTimeout to wait for high-quality downscaled version of
+ image to be ready, because there's nothing better we can do. If we fix
+ Bug 1006883, we can do away with this setTimeout.
+
+ For now, the setTimeout is just here to increase the likelihood that we
+ actually test the high-quality downscaled version of the image. If the
+ setTimeout happens to fire before the high-quality downscaled rendering is
+ ready, then this the test will pass without testing what it's trying to
+ test, which is fine as long as that's rare. -->
+<body style="margin: 0px" onload="setTimeout(snapshot, 50)">
+ <script>
+ var args = location.search.substring(1).split(',');
+ var image = document.createElement('img');
+ image.width = args[0];
+ image.height = args[1];
+ image.src = 'black-border-' + args[2] + '.png';
+ document.body.appendChild(image);
+ </script>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-2d.html b/image/test/reftest/downscaling/downscale-2d.html
new file mode 100644
index 0000000000..8d9547b73e
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-2d.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html reftest-zoom="0.67" class="reftest-wait">
+<head>
+ <script>
+ function snapshot() {
+ document.documentElement.removeAttribute('class');
+ }
+ </script>
+</head>
+<!-- NOTE: Using setTimeout to wait for high-quality downscaled version of
+ image to be ready, because there's nothing better we can do. If we fix
+ Bug 1006883, we can do away with this setTimeout.
+
+ For now, the setTimeout is just here to increase the likelihood that we
+ actually test the high-quality downscaled version of the image. If the
+ setTimeout happens to fire before the high-quality downscaled rendering is
+ ready, then this the test will pass without testing what it's trying to
+ test, which is fine as long as that's rare. -->
+<body style="margin: 0px" onload="setTimeout(snapshot, 50)">
+ <script>
+ var args = location.search.substring(1).split(',');
+ var image = document.createElement('img');
+ image.width = args[0];
+ image.height = args[1];
+ image.src = 'black-border-' + args[2] + '.png';
+ document.body.appendChild(image);
+ </script>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-2e.html b/image/test/reftest/downscaling/downscale-2e.html
new file mode 100644
index 0000000000..c3d0d771f3
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-2e.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html reftest-zoom="0.5" class="reftest-wait">
+<head>
+ <script>
+ function snapshot() {
+ document.documentElement.removeAttribute('class');
+ }
+ </script>
+</head>
+<!-- NOTE: Using setTimeout to wait for high-quality downscaled version of
+ image to be ready, because there's nothing better we can do. If we fix
+ Bug 1006883, we can do away with this setTimeout.
+
+ For now, the setTimeout is just here to increase the likelihood that we
+ actually test the high-quality downscaled version of the image. If the
+ setTimeout happens to fire before the high-quality downscaled rendering is
+ ready, then this the test will pass without testing what it's trying to
+ test, which is fine as long as that's rare. -->
+<body style="margin: 0px" onload="setTimeout(snapshot, 50)">
+ <script>
+ var args = location.search.substring(1).split(',');
+ var image = document.createElement('img');
+ image.width = args[0];
+ image.height = args[1];
+ image.src = 'black-border-' + args[2] + '.png';
+ document.body.appendChild(image);
+ </script>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-2f.html b/image/test/reftest/downscaling/downscale-2f.html
new file mode 100644
index 0000000000..42cfad1f57
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-2f.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html reftest-zoom="0.3" class="reftest-wait">
+<head>
+ <script>
+ function snapshot() {
+ document.documentElement.removeAttribute('class');
+ }
+ </script>
+</head>
+<!-- NOTE: Using setTimeout to wait for high-quality downscaled version of
+ image to be ready, because there's nothing better we can do. If we fix
+ Bug 1006883, we can do away with this setTimeout.
+
+ For now, the setTimeout is just here to increase the likelihood that we
+ actually test the high-quality downscaled version of the image. If the
+ setTimeout happens to fire before the high-quality downscaled rendering is
+ ready, then this the test will pass without testing what it's trying to
+ test, which is fine as long as that's rare. -->
+<body style="margin: 0px" onload="setTimeout(snapshot, 50)">
+ <script>
+ var args = location.search.substring(1).split(',');
+ var image = document.createElement('img');
+ image.width = args[0];
+ image.height = args[1];
+ image.src = 'black-border-' + args[2] + '.png';
+ document.body.appendChild(image);
+ </script>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-32px-ref.html b/image/test/reftest/downscaling/downscale-32px-ref.html
new file mode 100644
index 0000000000..1caf3c73bf
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-32px-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html>
+<body style="margin: 0px">
+ <img src="lime-red-32px.png">
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-32px.html b/image/test/reftest/downscaling/downscale-32px.html
new file mode 100644
index 0000000000..f5fce324d9
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-32px.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html class="reftest-wait">
+<head>
+ <script>
+ function snapshot() {
+ document.documentElement.removeAttribute('class');
+ }
+ </script>
+</head>
+<!-- NOTE: Using setTimeout to wait for high-quality downscaled version of
+ image to be ready, because there's nothing better we can do. If we fix
+ Bug 1006883, we can do away with this setTimeout.
+
+ For now, the setTimeout is just here to increase the likelihood that we
+ actually test the high-quality downscaled version of the image. If the
+ setTimeout happens to fire before the high-quality downscaled rendering is
+ ready, then this the test will pass without testing what it's trying to
+ test, which is fine as long as that's rare. -->
+<body style="margin: 0px" onload="setTimeout(snapshot, 50)">
+ <script>
+ var args = location.search.substring(1).split(',');
+ var image = document.createElement('img');
+ image.width = "32";
+ image.height = "32";
+ image.src = 'lime-red-256px' + location.search.substring(1);
+ document.body.appendChild(image);
+ </script>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-8px.html b/image/test/reftest/downscaling/downscale-8px.html
new file mode 100644
index 0000000000..c0586a3657
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-8px.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Image reftest wrapper</title>
+<style type="text/css">
+ #image1 { background-color: rgb(10, 250, 100); }
+</style>
+<script>
+ // The image is loaded async after the page loads.
+ // Wait for it to finish loading.
+ function onImageLoad() {
+ document.documentElement.removeAttribute("class");
+ };
+</script>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img width="8px" id="image1" alt=" ">
+<script>
+ // Use as "wrapper.html?image.png"
+ var imgURL = document.location.search.substr(1);
+ document.images[0].onload = onImageLoad;
+ document.images[0].onerror = onImageLoad;
+ document.images[0].src = imgURL;
+</script>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-moz-icon-1-ref.html b/image/test/reftest/downscaling/downscale-moz-icon-1-ref.html
new file mode 100644
index 0000000000..a7dd5ab8aa
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-moz-icon-1-ref.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html class="reftest-wait">
+<head>
+ <meta charset="utf-8" />
+ <title>Reference for downscaling moz-icon images (bug 1261964)</title>
+ <script>
+ function beginTest() {
+ var canvas = document.getElementById("canvas");
+ var image = new Image();
+
+ image.onload = function() {
+ // When image loads: draw it to canvas, scale down the canvas, and
+ // then let the reftest snapshot happen.
+ // The image can be larger than the requested size, so we resize the
+ // canvas to match it.
+ canvas.width = image.width;
+ canvas.height = image.height;
+ var ctx = canvas.getContext("2d");
+ ctx.drawImage(image, 0, 0);
+ canvas.setAttribute("class", "downscale");
+ document.documentElement.removeAttribute("class");
+ }
+
+ // Kick off the image load:
+ image.src = "moz-icon://bogus-unrecognized-icon?size=100";
+ }
+ </script>
+ <style>
+ body { margin: 0; }
+ .downscale {
+ transform-origin: 0 0;
+ transform: scale(0.9);
+ }
+ </style>
+</head>
+<body onload="beginTest()">
+ <canvas id="canvas"></canvas>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-moz-icon-1.html b/image/test/reftest/downscaling/downscale-moz-icon-1.html
new file mode 100644
index 0000000000..ba37951274
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-moz-icon-1.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>Testcase for downscaling moz-icon images (bug 1261964)</title>
+ <style>
+ body { margin: 0; }
+ .downscale {
+ transform-origin: 0 0;
+ transform: scale(0.9);
+ }
+ </style>
+</head>
+<body>
+ <img class="downscale" src="moz-icon://bogus-unrecognized-icon?size=100">
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-orient-ref.html b/image/test/reftest/downscaling/downscale-orient-ref.html
new file mode 100644
index 0000000000..e32141868f
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-orient-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html class="reftest-wait">
+<head>
+ <script>
+ function snapshot() {
+ document.documentElement.removeAttribute('class');
+ }
+ </script>
+</head>
+<!-- NOTE: Using setTimeout to wait for high-quality downscaled version of
+ image to be ready, because there's nothing better we can do. If we fix
+ Bug 1006883, we can do away with this setTimeout.
+
+ For now, the setTimeout is just here to increase the likelihood that we
+ actually test the high-quality downscaled version of the image. If the
+ setTimeout happens to fire before the high-quality downscaled rendering is
+ ready, then this the test will pass without testing what it's trying to
+ test, which is fine as long as that's rare. -->
+<body onload="setTimeout(snapshot, 50)">
+ <img src="image-pre-rotated-90-deg.jpg" style="width: 50px; height: 25px;">
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-orient-ref.png b/image/test/reftest/downscaling/downscale-orient-ref.png
new file mode 100644
index 0000000000..0db684e0d7
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-orient-ref.png
Binary files differ
diff --git a/image/test/reftest/downscaling/downscale-orient.html b/image/test/reftest/downscaling/downscale-orient.html
new file mode 100644
index 0000000000..11b849b27e
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-orient.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html class="reftest-wait">
+<head>
+ <script>
+ function snapshot() {
+ document.documentElement.removeAttribute('class');
+ }
+ </script>
+</head>
+<!-- NOTE: Using setTimeout to wait for high-quality downscaled version of
+ image to be ready, because there's nothing better we can do. If we fix
+ Bug 1006883, we can do away with this setTimeout.
+
+ For now, the setTimeout is just here to increase the likelihood that we
+ actually test the high-quality downscaled version of the image. If the
+ setTimeout happens to fire before the high-quality downscaled rendering is
+ ready, then this the test will pass without testing what it's trying to
+ test, which is fine as long as that's rare. -->
+<body onload="setTimeout(snapshot, 50)">
+ <img src="../../../../layout/reftests/image/image-exif-90-deg.jpg" style="width: 50px; height: 25px;">
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-png.html b/image/test/reftest/downscaling/downscale-png.html
new file mode 100644
index 0000000000..4752b2155a
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-png.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html reftest-zoom="1.0" class="reftest-wait">
+<head>
+ <script>
+ function snapshot() {
+ document.documentElement.removeAttribute('class');
+ }
+ </script>
+</head>
+<!-- NOTE: Using setTimeout to wait for high-quality downscaled version of
+ image to be ready, because there's nothing better we can do. If we fix
+ Bug 1006883, we can do away with this setTimeout.
+
+ For now, the setTimeout is just here to increase the likelihood that we
+ actually test the high-quality downscaled version of the image. If the
+ setTimeout happens to fire before the high-quality downscaled rendering is
+ ready, then this the test will pass without testing what it's trying to
+ test, which is fine as long as that's rare. -->
+<body style="margin: 0px" onload="setTimeout(snapshot, 50)">
+ <script>
+ var args = location.search.substring(1).split(',');
+ var image = document.createElement('img');
+ image.width = args[0];
+ image.height = args[1];
+ image.src = 'png-' + args[2] + '.png';
+ document.body.appendChild(image);
+ </script>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-svg-1-ref.html b/image/test/reftest/downscaling/downscale-svg-1-ref.html
new file mode 100644
index 0000000000..8935619ebd
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-svg-1-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html>
+<body style="margin: 0px">
+ <embed src="black-border-rect.svg" style="display: block">
+ <script>
+ var width = location.search.substring(1).split("&");
+ var embedElem = document.getElementsByTagName('embed')[0];
+ embedElem.style.width = width + 'px';
+ </script>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-svg-1a.html b/image/test/reftest/downscaling/downscale-svg-1a.html
new file mode 100644
index 0000000000..2263cc9982
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-svg-1a.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html reftest-zoom="1.0">
+<body style="margin: 0px">
+ <div style="width: 80px; height: 80px; background: url(black-border-rect.svg) no-repeat"></div>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-svg-1b.html b/image/test/reftest/downscaling/downscale-svg-1b.html
new file mode 100644
index 0000000000..9db239c7cd
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-svg-1b.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html reftest-zoom="0.9">
+<body style="margin: 0px">
+ <div style="width: 80px; height: 80px; background: url(black-border-rect.svg) no-repeat"></div>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-svg-1c.html b/image/test/reftest/downscaling/downscale-svg-1c.html
new file mode 100644
index 0000000000..f8babf0267
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-svg-1c.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html reftest-zoom="0.8">
+<body style="margin: 0px">
+ <div style="width: 80px; height: 80px; background: url(black-border-rect.svg) no-repeat"></div>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-svg-1d.html b/image/test/reftest/downscaling/downscale-svg-1d.html
new file mode 100644
index 0000000000..9a56a51de0
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-svg-1d.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html reftest-zoom="0.67">
+<body style="margin: 0px">
+ <div style="width: 80px; height: 80px; background: url(black-border-rect.svg) no-repeat"></div>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-svg-1e.html b/image/test/reftest/downscaling/downscale-svg-1e.html
new file mode 100644
index 0000000000..732ac22c96
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-svg-1e.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html reftest-zoom="0.5">
+<body style="margin: 0px">
+ <div style="width: 80px; height: 80px; background: url(black-border-rect.svg) no-repeat"></div>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/downscale-svg-1f.html b/image/test/reftest/downscaling/downscale-svg-1f.html
new file mode 100644
index 0000000000..0124682c70
--- /dev/null
+++ b/image/test/reftest/downscaling/downscale-svg-1f.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html reftest-zoom="0.3">
+<body style="margin: 0px">
+ <div style="width: 80px; height: 80px; background: url(black-border-rect.svg) no-repeat"></div>
+</body>
+</html>
diff --git a/image/test/reftest/downscaling/ff-0RGB.ico b/image/test/reftest/downscaling/ff-0RGB.ico
new file mode 100644
index 0000000000..56116b9f6a
--- /dev/null
+++ b/image/test/reftest/downscaling/ff-0RGB.ico
Binary files differ
diff --git a/image/test/reftest/downscaling/ff-0RGB.png b/image/test/reftest/downscaling/ff-0RGB.png
new file mode 100644
index 0000000000..749ffcdfb3
--- /dev/null
+++ b/image/test/reftest/downscaling/ff-0RGB.png
Binary files differ
diff --git a/image/test/reftest/downscaling/ff-ARGB.ico b/image/test/reftest/downscaling/ff-ARGB.ico
new file mode 100644
index 0000000000..4681dc6495
--- /dev/null
+++ b/image/test/reftest/downscaling/ff-ARGB.ico
Binary files differ
diff --git a/image/test/reftest/downscaling/ff-ARGB.png b/image/test/reftest/downscaling/ff-ARGB.png
new file mode 100644
index 0000000000..74ea0e2f39
--- /dev/null
+++ b/image/test/reftest/downscaling/ff-ARGB.png
Binary files differ
diff --git a/image/test/reftest/downscaling/huge-1.html b/image/test/reftest/downscaling/huge-1.html
new file mode 100644
index 0000000000..6685600086
--- /dev/null
+++ b/image/test/reftest/downscaling/huge-1.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html><meta charset=utf-8>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<body style="margin: 0px">
+ <script>
+ let args = location.search.substring(1).split(',');
+ document.write(`<img src="${args[0]}" width="${args[1]}" height="${args[2]}">`);
+ </script>
+</body>
diff --git a/image/test/reftest/downscaling/image-pre-rotated-90-deg.jpg b/image/test/reftest/downscaling/image-pre-rotated-90-deg.jpg
new file mode 100644
index 0000000000..b8817f9bf5
--- /dev/null
+++ b/image/test/reftest/downscaling/image-pre-rotated-90-deg.jpg
Binary files differ
diff --git a/image/test/reftest/downscaling/lime-red-256px-bmp-in.ico b/image/test/reftest/downscaling/lime-red-256px-bmp-in.ico
new file mode 100644
index 0000000000..b372cba4a2
--- /dev/null
+++ b/image/test/reftest/downscaling/lime-red-256px-bmp-in.ico
Binary files differ
diff --git a/image/test/reftest/downscaling/lime-red-256px-png-in.ico b/image/test/reftest/downscaling/lime-red-256px-png-in.ico
new file mode 100644
index 0000000000..e8578d2934
--- /dev/null
+++ b/image/test/reftest/downscaling/lime-red-256px-png-in.ico
Binary files differ
diff --git a/image/test/reftest/downscaling/lime-red-256px.bmp b/image/test/reftest/downscaling/lime-red-256px.bmp
new file mode 100644
index 0000000000..3dc808970f
--- /dev/null
+++ b/image/test/reftest/downscaling/lime-red-256px.bmp
Binary files differ
diff --git a/image/test/reftest/downscaling/lime-red-256px.gif b/image/test/reftest/downscaling/lime-red-256px.gif
new file mode 100644
index 0000000000..f9f669aa4d
--- /dev/null
+++ b/image/test/reftest/downscaling/lime-red-256px.gif
Binary files differ
diff --git a/image/test/reftest/downscaling/lime-red-256px.jpg b/image/test/reftest/downscaling/lime-red-256px.jpg
new file mode 100644
index 0000000000..ac8efdf360
--- /dev/null
+++ b/image/test/reftest/downscaling/lime-red-256px.jpg
Binary files differ
diff --git a/image/test/reftest/downscaling/lime-red-256px.png b/image/test/reftest/downscaling/lime-red-256px.png
new file mode 100644
index 0000000000..2be2e05a59
--- /dev/null
+++ b/image/test/reftest/downscaling/lime-red-256px.png
Binary files differ
diff --git a/image/test/reftest/downscaling/lime-red-256px.svg b/image/test/reftest/downscaling/lime-red-256px.svg
new file mode 100644
index 0000000000..530ae6d6d5
--- /dev/null
+++ b/image/test/reftest/downscaling/lime-red-256px.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
+ width="256" height="256">
+ <rect width="50%" height="100%" fill="lime"/>
+ <rect x="50%" width="50%" height="100%" fill="red"/>
+</svg>
diff --git a/image/test/reftest/downscaling/lime-red-32px.png b/image/test/reftest/downscaling/lime-red-32px.png
new file mode 100644
index 0000000000..bfa2e7b737
--- /dev/null
+++ b/image/test/reftest/downscaling/lime-red-32px.png
Binary files differ
diff --git a/image/test/reftest/downscaling/png-interlaced.png b/image/test/reftest/downscaling/png-interlaced.png
new file mode 100644
index 0000000000..a938d0bd6a
--- /dev/null
+++ b/image/test/reftest/downscaling/png-interlaced.png
Binary files differ
diff --git a/image/test/reftest/downscaling/png-normal.png b/image/test/reftest/downscaling/png-normal.png
new file mode 100644
index 0000000000..c2780fdd93
--- /dev/null
+++ b/image/test/reftest/downscaling/png-normal.png
Binary files differ
diff --git a/image/test/reftest/downscaling/reftest.list b/image/test/reftest/downscaling/reftest.list
new file mode 100644
index 0000000000..f01780ffaa
--- /dev/null
+++ b/image/test/reftest/downscaling/reftest.list
@@ -0,0 +1,217 @@
+# Reftests for downscaling
+#
+# Downscaling can be a lossy process, so a bit of mismatch is acceptable here,
+# as long as it's barely noticeable visually. When necessary, this can be
+# explicitly allowed via 'fuzzy'/'fuzzy-if' annotations.
+#
+# Many of these tests check primarily that we don't lose rows or columns of
+# pixels when downscaling by making sure that the result isn't too similar to
+# about:blank. A small amount of fuzziness is used to ensure that the tests
+# don't pass because of very slight deviations; passing tests should be
+# substantially different from about:blank. This fuzziness should *not* be
+# removed as doing so would make the tests pass in situations where they
+# shouldn't.
+#
+# IMPORTANT: For robustness, each test should be listed *twice* in this
+# manifest -- once with the high quality downscaling pref disabled, and once
+# with this pref enabled. The pref is set via "defaults", so
+# simply appending a new test to the lists below each of those lines should be
+# sufficient.
+#
+# Also note that Mac OS X has its own system-level downscaling algorithm, so
+# tests here may need Mac-specific "fuzzy-if(cocoaWidget,...)" annotations.
+# Similarly, modern versions of Windows have slightly different downscaling
+# behavior than other platforms, and may require "fuzzy-if(winWidget,...)".
+
+
+# RUN TESTS NOT AFFECTED BY DOWNSCALE-DURING-DECODE:
+# ==================================================
+fuzzy(0-14,0-416) == downscale-svg-1a.html downscale-svg-1-ref.html?80
+fuzzy(65-65,468-480) == downscale-svg-1b.html downscale-svg-1-ref.html?72
+fuzzy(0-8,0-292) == downscale-svg-1c.html downscale-svg-1-ref.html?64
+fuzzy(7-7,208-208) == downscale-svg-1d.html downscale-svg-1-ref.html?53
+fuzzy(54-55,178-178) == downscale-svg-1e.html downscale-svg-1-ref.html?40
+fuzzy(64-64,31-31) == downscale-svg-1f.html downscale-svg-1-ref.html?24
+
+# RUN TESTS WITH DOWNSCALE-DURING-DECODE DISABLED:
+# ================================================
+defaults pref(image.downscale-during-decode.enabled,false)
+
+fuzzy-if(winWidget,0-16,0-20) fuzzy-if(cocoaWidget,0-106,0-31) == downscale-1.html downscale-1-ref.html
+
+fuzzy(0-20,0-999) != downscale-2a.html?203,52,left about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?203,52,left about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?203,52,left about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?203,52,left about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?203,52,left about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?205,53,left about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?205,53,left about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?205,53,left about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?205,53,left about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?205,53,left about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?203,52,right about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?203,52,right about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?203,52,right about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?203,52,right about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?203,52,right about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?205,53,right about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?205,53,right about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?205,53,right about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?205,53,right about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?205,53,right about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?203,52,top about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?203,52,top about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?203,52,top about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?203,52,top about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?203,52,top about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?205,53,top about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?205,53,top about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?205,53,top about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?205,53,top about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?205,53,top about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?203,52,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?203,52,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?203,52,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?203,52,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?203,52,bottom about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?205,53,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?205,53,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?205,53,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?205,53,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?205,53,bottom about:blank
+
+# Skip on Android because it runs reftests via http, and moz-icon isn't
+# accessible from http/https origins anymore.
+fuzzy(0-27,0-3940) fuzzy-if(gtkWidget,0-0,0-0) skip-if(Android) fuzzy-if(appleSilicon,0-20,0-10123) == downscale-moz-icon-1.html downscale-moz-icon-1-ref.html # gtkWidget Bug 1592059: regular is 2616, no-accel is 0, qr passes with 0
+
+== downscale-png.html?16,16,interlaced downscale-png.html?16,16,normal
+== downscale-png.html?24,24,interlaced downscale-png.html?24,24,normal
+
+# Non-transparent and transparent ICO images
+== downscale-16px.html?ff-0RGB.ico downscale-16px.html?ff-0RGB.png
+fuzzy(0-1,0-1) fuzzy-if(gtkWidget&&swgl,1-1,1-1) == downscale-16px.html?ff-ARGB.ico downscale-16px.html?ff-ARGB.png
+
+# Test downscaling from all supported formats from 256 to 32.
+== downscale-32px.html?.bmp downscale-32px-ref.html
+== downscale-32px.html?.gif downscale-32px-ref.html
+fuzzy(0-1,0-1024) == downscale-32px.html?.jpg downscale-32px-ref.html
+== downscale-32px.html?.png downscale-32px-ref.html
+== downscale-32px.html?.svg downscale-32px-ref.html
+== downscale-32px.html?-bmp-in.ico downscale-32px-ref.html
+== downscale-32px.html?-png-in.ico downscale-32px-ref.html
+
+# Test downscaling a JPEG with orientation metadata.
+fuzzy(0-1,0-50) == downscale-orient.html downscale-orient-ref.html
+
+# RUN TESTS WITH DOWNSCALE-DURING-DECODE ENABLED:
+# ===============================================
+defaults pref(image.downscale-during-decode.enabled,true)
+
+fuzzy(0-31,0-127) fuzzy-if(d2d,0-31,0-147) == downscale-1.html downscale-1-ref.html # intermittently 147 pixels on win7 accelerated only (not win8)
+
+fuzzy(0-20,0-999) != downscale-2a.html?203,52,left about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?203,52,left about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?203,52,left about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?203,52,left about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?203,52,left about:blank
+fuzzy(0-20,0-999) != downscale-2f.html?203,52,left about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?205,53,left about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?205,53,left about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?205,53,left about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?205,53,left about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?205,53,left about:blank
+fuzzy(0-20,0-999) != downscale-2f.html?205,53,left about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?203,52,right about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?203,52,right about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?203,52,right about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?203,52,right about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?203,52,right about:blank
+fuzzy(0-20,0-999) != downscale-2f.html?203,52,right about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?205,53,right about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?205,53,right about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?205,53,right about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?205,53,right about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?205,53,right about:blank
+fuzzy(0-20,0-999) != downscale-2f.html?205,53,right about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?203,52,top about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?203,52,top about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?203,52,top about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?203,52,top about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?203,52,top about:blank
+fuzzy(0-20,0-999) != downscale-2f.html?203,52,top about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?205,53,top about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?205,53,top about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?205,53,top about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?205,53,top about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?205,53,top about:blank
+fuzzy(0-20,0-999) != downscale-2f.html?205,53,top about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?203,52,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?203,52,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?203,52,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?203,52,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?203,52,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2f.html?203,52,bottom about:blank
+
+fuzzy(0-20,0-999) != downscale-2a.html?205,53,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2b.html?205,53,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2c.html?205,53,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2d.html?205,53,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2e.html?205,53,bottom about:blank
+fuzzy(0-20,0-999) != downscale-2f.html?205,53,bottom about:blank
+
+# Skip on Android because it runs reftests via http, and moz-icon isn't
+# accessible from http/https origins anymore.
+fuzzy(0-53,0-6391) fuzzy-if(appleSilicon,0-20,0-11605) fuzzy-if(gtkWidget,18-19,5502-5568) skip-if(Android) == downscale-moz-icon-1.html downscale-moz-icon-1-ref.html # gtkWidget Bug 1592059
+
+== downscale-png.html?16,16,interlaced downscale-png.html?16,16,normal
+== downscale-png.html?24,24,interlaced downscale-png.html?24,24,normal
+
+# Non-transparent and transparent ICO images
+fuzzy(0-1,0-3) == downscale-16px.html?ff-0RGB.ico downscale-16px.html?ff-0RGB.png
+fuzzy(0-3,0-32) fuzzy-if(swgl,3-3,33-33) == downscale-16px.html?ff-ARGB.ico downscale-16px.html?ff-ARGB.png
+
+# Upside-down (negative height) BMP
+== downscale-8px.html?top-to-bottom-16x16-24bpp.bmp downscale-8px.html?bmp-size-16x16-24bpp.png
+
+# Test downscaling from all supported formats from 256 to 32.
+fuzzy(0-18,0-128) == downscale-32px.html?.bmp downscale-32px-ref.html
+fuzzy(0-18,0-128) == downscale-32px.html?.gif downscale-32px-ref.html
+fuzzy(0-19,0-992) == downscale-32px.html?.jpg downscale-32px-ref.html
+fuzzy(0-18,0-128) == downscale-32px.html?.png downscale-32px-ref.html
+== downscale-32px.html?.svg downscale-32px-ref.html
+fuzzy(0-18,0-128) == downscale-32px.html?-bmp-in.ico downscale-32px-ref.html
+fuzzy(0-18,0-128) == downscale-32px.html?-png-in.ico downscale-32px-ref.html
+
+# Test downscaling a JPEG with orientation metadata.
+fuzzy(0-4,0-18) == downscale-orient.html downscale-orient-ref.html
+
+# Test images taller or wider than 32767 pixels.
+== huge-1.html?100x32768.png,100,100 huge-1.html?100x100.png,100,100
+== huge-1.html?100x32768.png,100,32768 huge-1.html?100x100.png,100,32768
+== huge-1.html?32768x100.png,100,100 huge-1.html?100x100.png,100,100
+== huge-1.html?32768x100.png,32768,100 huge-1.html?100x100.png,32768,100
+== huge-1.html?100x32768.gif,100,100 huge-1.html?100x100.gif,100,100
+== huge-1.html?100x32768.gif,100,32768 huge-1.html?100x100.gif,100,32768
+== huge-1.html?32768x100.gif,100,100 huge-1.html?100x100.gif,100,100
+== huge-1.html?32768x100.gif,32768,100 huge-1.html?100x100.gif,32768,100
+== huge-1.html?100x32768.jpg,100,100 huge-1.html?100x100.jpg,100,100
+== huge-1.html?100x32768.jpg,100,32768 huge-1.html?100x100.jpg,100,32768
+== huge-1.html?32768x100.jpg,100,100 huge-1.html?100x100.jpg,100,100
+== huge-1.html?32768x100.jpg,32768,100 huge-1.html?100x100.jpg,32768,100
+
+# Only need to run these with downscaling on
+!= 1421191-1.html about:blank
+== 1404366-1.html about:blank
diff --git a/image/test/reftest/downscaling/top-to-bottom-16x16-24bpp.bmp b/image/test/reftest/downscaling/top-to-bottom-16x16-24bpp.bmp
new file mode 100644
index 0000000000..bd18f85d48
--- /dev/null
+++ b/image/test/reftest/downscaling/top-to-bottom-16x16-24bpp.bmp
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/ImageDocument.css b/image/test/reftest/encoders-lossless/ImageDocument.css
new file mode 100644
index 0000000000..9a41b4c161
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/ImageDocument.css
@@ -0,0 +1,16 @@
+body {
+ background: #222 url("chrome://global/skin/media/imagedoc-darknoise.png");
+ margin: 0;
+}
+
+img {
+ display: block;
+ position: absolute;
+ margin: auto;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background: hsl(0,0%,90%) url("chrome://global/skin/media/imagedoc-lightnoise.png");
+ color: #222;
+}
diff --git a/image/test/reftest/encoders-lossless/encoder.html b/image/test/reftest/encoders-lossless/encoder.html
new file mode 100644
index 0000000000..6e07995ae3
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/encoder.html
@@ -0,0 +1,113 @@
+<html class="reftest-wait">
+<head>
+ <title>Image reftest wrapper</title>
+ <link rel="stylesheet" href="ImageDocument.css">
+ <style type="text/css">
+ #image_from_encoder { background-color: rgb(10, 100, 250); }
+ </style>
+
+ <script>
+ // Parse out the URL command line params
+ // Valid options are:
+ // - img=<reference image to use>
+ // - mime=<mime type>
+ // - options=<canvas toDataURL encoder options>
+ // Example:
+ // encoder.html?img=escape(reference_image.png)
+ // &mime=escape(image/ico)
+ // &options=escape(-moz-parse-options:bpp=24;format=png)
+ var getVars = {};
+ function buildValue(sValue)
+ {
+ if (/^\s*$/.test(sValue)) {
+ return null;
+ }
+ if (/^(true|false)$/i.test(sValue)) {
+ return sValue.toLowerCase() === "true";
+ }
+ if (isFinite(sValue)) {
+ return parseFloat(sValue);
+ }
+ if (isFinite(Date.parse(sValue))) {
+ return new Date(sValue);
+ }
+ return sValue;
+ }
+ if (window.location.search.length > 1) {
+ var couple, couples = window.location.search.substr(1).split("&");
+ for (var couplId = 0; couplId < couples.length; couplId++) {
+ couple = couples[couplId].split("=");
+ getVars[unescape(couple[0])] = couple.length > 1 ?
+ buildValue(unescape(couple[1])) : null;
+ }
+ }
+
+ // Create the image that we will load the reference image to
+ var img = new Image();
+
+ // Create the canvas that we will draw the image img onto and
+ // eventually call toDataURL to invoke the encoder on
+ var canvas = document.createElement("canvas");
+
+ // Starts the test by loading the reference image
+ function runTest()
+ {
+ // Load the reference image to start the test
+ img.onload = onReferenceImageLoad;
+ img.onerror = onReferenceImageLoad;
+ img.src = getVars.img;
+ }
+
+ // Once the encoded image from the canvas is loaded we can
+ // let the reftest compare
+ function onEncodedImageLoad()
+ {
+ document.documentElement.removeAttribute("class");
+ }
+
+ // Once the image loads async, we then draw the image onto the canvas,
+ // and call canvas.toDataURL to invoke the encoder, and then set a new
+ // image to the encoded data URL
+ function onReferenceImageLoad()
+ {
+ // mimeType will hold the mime type of which encoder to invoke
+ var mimeType = getVars.mime;
+ // parseOptions will hold the encoder options to use
+ var parseOptions = getVars.options;
+
+ // Obtain the canvas and draw the reference image
+ canvas.width = img.width;
+ canvas.height = img.height;
+ var ctx = canvas.getContext('2d')
+ ctx.drawImage(img, 0, 0);
+
+ // Obtain the data URL with parsing options if specified
+ var dataURL;
+ if (parseOptions)
+ dataURL = canvas.toDataURL(mimeType, parseOptions);
+ else
+ dataURL = canvas.toDataURL(mimeType);
+
+ // Setup async image loaded events
+ var image_from_encoder = document.getElementById('image_from_encoder');
+ image_from_encoder.onload = onEncodedImageLoad;
+ image_from_encoder.onerror = onEncodedImageLoad;
+
+ // Only set the image if we have the correct mime type
+ // because we want to fail the ref test if toDataURL fell
+ // back to image/png
+ if (dataURL.substring(0, mimeType.length+5) == "data:" + mimeType) {
+ // Set the image to the BMP data URL
+ image_from_encoder.src = dataURL;
+ } else {
+ // Blank image so that we won't have to timeout the reftest
+ image_from_encoder.src = "data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw%3D%3D";
+ }
+ };
+ </script>
+</head>
+
+<body onload="runTest()">
+<img id="image_from_encoder">
+</body>
+</html>
diff --git a/image/test/reftest/encoders-lossless/reftest.list b/image/test/reftest/encoders-lossless/reftest.list
new file mode 100644
index 0000000000..fe8fbc5bc5
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/reftest.list
@@ -0,0 +1,175 @@
+# Encoder ref tests
+# These reftests must be run as HTTP because of canvas' origin-clean security
+# file:// URLs are always considered from a different origin unless same URL
+#
+# The test will copy a PNG image to a canvas, then use canvas.toDataUrl to get
+# the data, then set the data to a new image hence invoking the appropriate
+# encoder.
+#
+# The tests should only be used with lossless encoders.
+#
+# Valid arguments for encoder.html in the query string:
+# - img=<reference image to use>
+# - mime=<mime type>
+# - options=<canvas toDataURL encoder options>
+# Example:
+# encoder.html?img=escape(reference_image.png)
+# &mime=escape(image/vnd.microsoft.icon)
+# &options=escape(-moz-parse-options:bpp=24;format=png)
+
+# PNG
+HTTP == size-1x1.png encoder.html?img=size-1x1.png&mime=image/png
+HTTP == size-2x2.png encoder.html?img=size-2x2.png&mime=image/png
+HTTP == size-3x3.png encoder.html?img=size-3x3.png&mime=image/png
+HTTP == size-4x4.png encoder.html?img=size-4x4.png&mime=image/png
+HTTP == size-5x5.png encoder.html?img=size-5x5.png&mime=image/png
+HTTP == size-6x6.png encoder.html?img=size-6x6.png&mime=image/png
+HTTP == size-7x7.png encoder.html?img=size-7x7.png&mime=image/png
+HTTP == size-8x8.png encoder.html?img=size-8x8.png&mime=image/png
+HTTP == size-9x9.png encoder.html?img=size-9x9.png&mime=image/png
+HTTP == size-15x15.png encoder.html?img=size-15x15.png&mime=image/png
+HTTP == size-16x16.png encoder.html?img=size-16x16.png&mime=image/png
+HTTP == size-17x17.png encoder.html?img=size-17x17.png&mime=image/png
+HTTP == size-31x31.png encoder.html?img=size-31x31.png&mime=image/png
+HTTP == size-32x32.png encoder.html?img=size-32x32.png&mime=image/png
+HTTP == size-33x33.png encoder.html?img=size-33x33.png&mime=image/png
+
+# BMP using default parse options
+HTTP == size-1x1.png encoder.html?img=size-1x1.png&mime=image/bmp
+HTTP == size-2x2.png encoder.html?img=size-2x2.png&mime=image/bmp
+HTTP == size-3x3.png encoder.html?img=size-3x3.png&mime=image/bmp
+HTTP == size-4x4.png encoder.html?img=size-4x4.png&mime=image/bmp
+HTTP == size-5x5.png encoder.html?img=size-5x5.png&mime=image/bmp
+HTTP == size-6x6.png encoder.html?img=size-6x6.png&mime=image/bmp
+HTTP == size-7x7.png encoder.html?img=size-7x7.png&mime=image/bmp
+HTTP == size-8x8.png encoder.html?img=size-8x8.png&mime=image/bmp
+HTTP == size-9x9.png encoder.html?img=size-9x9.png&mime=image/bmp
+HTTP == size-15x15.png encoder.html?img=size-15x15.png&mime=image/bmp
+HTTP == size-16x16.png encoder.html?img=size-16x16.png&mime=image/bmp
+HTTP == size-17x17.png encoder.html?img=size-17x17.png&mime=image/bmp
+HTTP == size-31x31.png encoder.html?img=size-31x31.png&mime=image/bmp
+HTTP == size-32x32.png encoder.html?img=size-32x32.png&mime=image/bmp
+HTTP == size-33x33.png encoder.html?img=size-33x33.png&mime=image/bmp
+
+# BMP using image/bmp mime type and 32bpp parse options
+HTTP == size-1x1.png encoder.html?img=size-1x1.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-2x2.png encoder.html?img=size-2x2.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-3x3.png encoder.html?img=size-3x3.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-4x4.png encoder.html?img=size-4x4.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-5x5.png encoder.html?img=size-5x5.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-6x6.png encoder.html?img=size-6x6.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-7x7.png encoder.html?img=size-7x7.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-8x8.png encoder.html?img=size-8x8.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-9x9.png encoder.html?img=size-9x9.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-15x15.png encoder.html?img=size-15x15.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-16x16.png encoder.html?img=size-16x16.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-17x17.png encoder.html?img=size-17x17.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-31x31.png encoder.html?img=size-31x31.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-32x32.png encoder.html?img=size-32x32.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+HTTP == size-33x33.png encoder.html?img=size-33x33.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D32
+
+# BMP using image/bmp mime type and 24bpp parse options
+HTTP == size-1x1.png encoder.html?img=size-1x1.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-2x2.png encoder.html?img=size-2x2.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-3x3.png encoder.html?img=size-3x3.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-4x4.png encoder.html?img=size-4x4.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-5x5.png encoder.html?img=size-5x5.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-6x6.png encoder.html?img=size-6x6.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-7x7.png encoder.html?img=size-7x7.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-8x8.png encoder.html?img=size-8x8.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-9x9.png encoder.html?img=size-9x9.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-15x15.png encoder.html?img=size-15x15.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-16x16.png encoder.html?img=size-16x16.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-17x17.png encoder.html?img=size-17x17.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-31x31.png encoder.html?img=size-31x31.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-32x32.png encoder.html?img=size-32x32.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+HTTP == size-33x33.png encoder.html?img=size-33x33.png&mime=image/bmp&options=-moz-parse-options%3Abpp%3D24
+
+# ICO using default parse options
+HTTP == size-1x1.png encoder.html?img=size-1x1.png&mime=image/vnd.microsoft.icon
+HTTP == size-2x2.png encoder.html?img=size-2x2.png&mime=image/vnd.microsoft.icon
+HTTP == size-3x3.png encoder.html?img=size-3x3.png&mime=image/vnd.microsoft.icon
+HTTP == size-4x4.png encoder.html?img=size-4x4.png&mime=image/vnd.microsoft.icon
+HTTP == size-5x5.png encoder.html?img=size-5x5.png&mime=image/vnd.microsoft.icon
+HTTP == size-6x6.png encoder.html?img=size-6x6.png&mime=image/vnd.microsoft.icon
+HTTP == size-7x7.png encoder.html?img=size-7x7.png&mime=image/vnd.microsoft.icon
+HTTP == size-8x8.png encoder.html?img=size-8x8.png&mime=image/vnd.microsoft.icon
+HTTP == size-9x9.png encoder.html?img=size-9x9.png&mime=image/vnd.microsoft.icon
+HTTP == size-15x15.png encoder.html?img=size-15x15.png&mime=image/vnd.microsoft.icon
+HTTP == size-16x16.png encoder.html?img=size-16x16.png&mime=image/vnd.microsoft.icon
+HTTP == size-17x17.png encoder.html?img=size-17x17.png&mime=image/vnd.microsoft.icon
+HTTP == size-31x31.png encoder.html?img=size-31x31.png&mime=image/vnd.microsoft.icon
+HTTP == size-32x32.png encoder.html?img=size-32x32.png&mime=image/vnd.microsoft.icon
+HTTP == size-33x33.png encoder.html?img=size-33x33.png&mime=image/vnd.microsoft.icon
+HTTP == size-256x256.png encoder.html?img=size-256x256.png&mime=image/vnd.microsoft.icon
+
+# ICO using image/vnd.microsoft.icon mime type and 32bpp parse options with bmp
+HTTP == size-1x1.png encoder.html?img=size-1x1.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-2x2.png encoder.html?img=size-2x2.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-3x3.png encoder.html?img=size-3x3.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-4x4.png encoder.html?img=size-4x4.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-5x5.png encoder.html?img=size-5x5.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-6x6.png encoder.html?img=size-6x6.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-7x7.png encoder.html?img=size-7x7.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-8x8.png encoder.html?img=size-8x8.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-9x9.png encoder.html?img=size-9x9.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-15x15.png encoder.html?img=size-15x15.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-16x16.png encoder.html?img=size-16x16.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-17x17.png encoder.html?img=size-17x17.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-31x31.png encoder.html?img=size-31x31.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-32x32.png encoder.html?img=size-32x32.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-33x33.png encoder.html?img=size-33x33.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+HTTP == size-256x256.png encoder.html?img=size-256x256.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D32%3Bformat%3Dbmp
+
+# ICO using image/vnd.microsoft.icon mime type and 24bpp parse options with bmp
+HTTP == size-1x1.png encoder.html?img=size-1x1.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-2x2.png encoder.html?img=size-2x2.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-3x3.png encoder.html?img=size-3x3.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-4x4.png encoder.html?img=size-4x4.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-5x5.png encoder.html?img=size-5x5.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-6x6.png encoder.html?img=size-6x6.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-7x7.png encoder.html?img=size-7x7.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-8x8.png encoder.html?img=size-8x8.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-9x9.png encoder.html?img=size-9x9.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-15x15.png encoder.html?img=size-15x15.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-16x16.png encoder.html?img=size-16x16.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-17x17.png encoder.html?img=size-17x17.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-31x31.png encoder.html?img=size-31x31.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-32x32.png encoder.html?img=size-32x32.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-33x33.png encoder.html?img=size-33x33.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+HTTP == size-256x256.png encoder.html?img=size-256x256.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Abpp%3D24%3Bformat%3Dbmp
+
+# ICO using image/vnd.microsoft.icon mime type png
+HTTP == size-1x1.png encoder.html?img=size-1x1.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-2x2.png encoder.html?img=size-2x2.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-3x3.png encoder.html?img=size-3x3.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-4x4.png encoder.html?img=size-4x4.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-5x5.png encoder.html?img=size-5x5.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-6x6.png encoder.html?img=size-6x6.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-7x7.png encoder.html?img=size-7x7.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-8x8.png encoder.html?img=size-8x8.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-9x9.png encoder.html?img=size-9x9.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-15x15.png encoder.html?img=size-15x15.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-16x16.png encoder.html?img=size-16x16.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-17x17.png encoder.html?img=size-17x17.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-31x31.png encoder.html?img=size-31x31.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-32x32.png encoder.html?img=size-32x32.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-33x33.png encoder.html?img=size-33x33.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+HTTP == size-256x256.png encoder.html?img=size-256x256.png&mime=image/vnd.microsoft.icon&options=-moz-parse-options%3Aformat%3Dpng
+
+# WEBP
+HTTP == size-1x1.png encoder.html?img=size-1x1.png&mime=image/webp&options=1
+HTTP == size-2x2.png encoder.html?img=size-2x2.png&mime=image/webp&options=1
+HTTP == size-3x3.png encoder.html?img=size-3x3.png&mime=image/webp&options=1
+HTTP == size-4x4.png encoder.html?img=size-4x4.png&mime=image/webp&options=1
+HTTP == size-5x5.png encoder.html?img=size-5x5.png&mime=image/webp&options=1
+HTTP == size-6x6.png encoder.html?img=size-6x6.png&mime=image/webp&options=1
+HTTP == size-7x7.png encoder.html?img=size-7x7.png&mime=image/webp&options=1
+HTTP == size-8x8.png encoder.html?img=size-8x8.png&mime=image/webp&options=1
+HTTP == size-9x9.png encoder.html?img=size-9x9.png&mime=image/webp&options=1
+HTTP == size-15x15.png encoder.html?img=size-15x15.png&mime=image/webp&options=1
+HTTP == size-16x16.png encoder.html?img=size-16x16.png&mime=image/webp&options=1
+HTTP == size-17x17.png encoder.html?img=size-17x17.png&mime=image/webp&options=1
+HTTP == size-31x31.png encoder.html?img=size-31x31.png&mime=image/webp&options=1
+HTTP == size-32x32.png encoder.html?img=size-32x32.png&mime=image/webp&options=1
+HTTP == size-33x33.png encoder.html?img=size-33x33.png&mime=image/webp&options=1
diff --git a/image/test/reftest/encoders-lossless/size-15x15.png b/image/test/reftest/encoders-lossless/size-15x15.png
new file mode 100644
index 0000000000..e1287430d0
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-15x15.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-16x16.png b/image/test/reftest/encoders-lossless/size-16x16.png
new file mode 100644
index 0000000000..c04869e728
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-16x16.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-17x17.png b/image/test/reftest/encoders-lossless/size-17x17.png
new file mode 100644
index 0000000000..00fb8e4f37
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-17x17.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-1x1.png b/image/test/reftest/encoders-lossless/size-1x1.png
new file mode 100644
index 0000000000..c05f5fef89
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-1x1.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-256x256.png b/image/test/reftest/encoders-lossless/size-256x256.png
new file mode 100644
index 0000000000..84bfada761
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-256x256.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-2x2.png b/image/test/reftest/encoders-lossless/size-2x2.png
new file mode 100644
index 0000000000..e512d3f9b4
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-2x2.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-31x31.png b/image/test/reftest/encoders-lossless/size-31x31.png
new file mode 100644
index 0000000000..e4a8642514
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-31x31.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-32x32.png b/image/test/reftest/encoders-lossless/size-32x32.png
new file mode 100644
index 0000000000..3a6fbe8ee9
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-32x32.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-33x33.png b/image/test/reftest/encoders-lossless/size-33x33.png
new file mode 100644
index 0000000000..72ef7eb636
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-33x33.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-3x3.png b/image/test/reftest/encoders-lossless/size-3x3.png
new file mode 100644
index 0000000000..cb42ec4f87
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-3x3.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-4x4.png b/image/test/reftest/encoders-lossless/size-4x4.png
new file mode 100644
index 0000000000..e6afafd89a
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-4x4.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-5x5.png b/image/test/reftest/encoders-lossless/size-5x5.png
new file mode 100644
index 0000000000..a844aff76d
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-5x5.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-6x6.png b/image/test/reftest/encoders-lossless/size-6x6.png
new file mode 100644
index 0000000000..415c2d9c6a
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-6x6.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-7x7.png b/image/test/reftest/encoders-lossless/size-7x7.png
new file mode 100644
index 0000000000..ab2f892747
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-7x7.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-8x8.png b/image/test/reftest/encoders-lossless/size-8x8.png
new file mode 100644
index 0000000000..fe2ff40a1d
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-8x8.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/size-9x9.png b/image/test/reftest/encoders-lossless/size-9x9.png
new file mode 100644
index 0000000000..18ab4b25de
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/size-9x9.png
Binary files differ
diff --git a/image/test/reftest/encoders-lossless/test.png b/image/test/reftest/encoders-lossless/test.png
new file mode 100644
index 0000000000..3a6fbe8ee9
--- /dev/null
+++ b/image/test/reftest/encoders-lossless/test.png
Binary files differ
diff --git a/image/test/reftest/generic/accept-image-catchall-ref.html b/image/test/reftest/generic/accept-image-catchall-ref.html
new file mode 100644
index 0000000000..32daa9f5d6
--- /dev/null
+++ b/image/test/reftest/generic/accept-image-catchall-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=398066
+-->
+<html>
+<head>
+ <title>Accept: header should include image/* catchall</title>
+</head>
+<body>
+<img src="green.png">
+</body>
+</html>
diff --git a/image/test/reftest/generic/accept-image-catchall.html b/image/test/reftest/generic/accept-image-catchall.html
new file mode 100644
index 0000000000..bcacd9fd8f
--- /dev/null
+++ b/image/test/reftest/generic/accept-image-catchall.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=398066.
+https://bugzilla.mozilla.org/show_bug.cgi?id=1249474.
+-->
+<html>
+<head>
+ <title>Accept: header should include */* catchall</title>
+</head>
+<body>
+<img src="check-header.sjs">
+</body>
+</html>
diff --git a/image/test/reftest/generic/check-header.sjs b/image/test/reftest/generic/check-header.sjs
new file mode 100644
index 0000000000..afc39cb550
--- /dev/null
+++ b/image/test/reftest/generic/check-header.sjs
@@ -0,0 +1,72 @@
+const BinaryOutputStream = Components.Constructor("@mozilla.org/binaryoutputstream;1", "nsIBinaryOutputStream", "setOutputStream");
+
+function isCatchall(v)
+{
+ // "*/*" exactly
+ return /^\*\/\*$/.test(v);
+}
+
+/*
+# Python used to generate the following byte array
+def toHex(n):
+ if n < 16: return "0x" + hex(n)[2:].upper()
+ return "0x" + hex(n)[2:].upper()
+
+def hexFile(name):
+ f = open(name, "rb")
+ try:
+ while True:
+ print toHex(ord(f.read(1))) + ", ",
+ except:
+ pass
+
+hexFile("image/test/reftest/generic/green.png")
+*/
+
+const IMAGE_DATA =
+ [
+ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00,
+ 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00,
+ 0x00, 0x64, 0x08, 0x02, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x02, 0x03,
+ 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE,
+ 0x1C, 0xE9, 0x00, 0x00, 0x00, 0x9E, 0x49, 0x44, 0x41, 0x54, 0x78,
+ 0xDA, 0xED, 0xD0, 0x31, 0x01, 0x00, 0x00, 0x08, 0x03, 0xA0, 0x69,
+ 0xFF, 0xCE, 0x5A, 0xC1, 0xCF, 0x07, 0x22, 0x50, 0x99, 0x70, 0xD4,
+ 0x0A, 0x64, 0xC9, 0x92, 0x25, 0x4B, 0x96, 0x2C, 0x05, 0xB2, 0x64,
+ 0xC9, 0x92, 0x25, 0x4B, 0x96, 0x02, 0x59, 0xB2, 0x64, 0xC9, 0x92,
+ 0x25, 0x4B, 0x81, 0x2C, 0x59, 0xB2, 0x64, 0xC9, 0x92, 0xA5, 0x40,
+ 0x96, 0x2C, 0x59, 0xB2, 0x64, 0xC9, 0x52, 0x20, 0x4B, 0x96, 0x2C,
+ 0x59, 0xB2, 0x64, 0x29, 0x90, 0x25, 0x4B, 0x96, 0x2C, 0x59, 0xB2,
+ 0x14, 0xC8, 0x92, 0x25, 0x4B, 0x96, 0x2C, 0x59, 0x0A, 0x64, 0xC9,
+ 0x92, 0x25, 0x4B, 0x96, 0x2C, 0x05, 0xB2, 0x64, 0xC9, 0x92, 0x25,
+ 0x4B, 0x96, 0x02, 0x59, 0xB2, 0x64, 0xC9, 0x92, 0x25, 0x4B, 0x81,
+ 0x2C, 0x59, 0xB2, 0x64, 0xC9, 0x92, 0xA5, 0x40, 0x96, 0x2C, 0x59,
+ 0xB2, 0x64, 0xC9, 0x52, 0x20, 0x4B, 0x96, 0x2C, 0x59, 0xB2, 0x64,
+ 0x29, 0x90, 0x25, 0x4B, 0x96, 0x2C, 0x59, 0xB2, 0x14, 0xC8, 0x92,
+ 0x25, 0x4B, 0x96, 0x2C, 0x59, 0x0A, 0x64, 0xC9, 0xFA, 0xB6, 0x89,
+ 0x5F, 0x01, 0xC7, 0x24, 0x83, 0xB2, 0x0C, 0x00, 0x00, 0x00, 0x00,
+ 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82,
+ ];
+
+function handleRequest(request, response)
+{
+ response.setHeader("Content-Type", "text/plain", false);
+ response.setHeader("Cache-Control", "no-cache", false);
+
+ var accept = request.hasHeader("Accept")
+ ? request.getHeader("Accept")
+ : "";
+
+ if (accept.split(",").some(isCatchall))
+ {
+ response.setHeader("Content-Type", "image/png", false);
+
+ var stream = new BinaryOutputStream(response.bodyOutputStream);
+ stream.writeByteArray(IMAGE_DATA);
+ }
+ else
+ {
+ response.setStatusLine(request.httpVersion, 404, "Not found");
+ response.write("Accept header contained: " + accept);
+ }
+}
diff --git a/image/test/reftest/generic/green.png b/image/test/reftest/generic/green.png
new file mode 100644
index 0000000000..4718c00e62
--- /dev/null
+++ b/image/test/reftest/generic/green.png
Binary files differ
diff --git a/image/test/reftest/generic/moz-icon-1.html b/image/test/reftest/generic/moz-icon-1.html
new file mode 100644
index 0000000000..fb2dcea202
--- /dev/null
+++ b/image/test/reftest/generic/moz-icon-1.html
@@ -0,0 +1 @@
+<img class="downscale" src="moz-icon://bogus-unrecognized-icon?size=100">
diff --git a/image/test/reftest/generic/moz-icon-blank-1-almostref.html b/image/test/reftest/generic/moz-icon-blank-1-almostref.html
new file mode 100644
index 0000000000..38d5e1ec86
--- /dev/null
+++ b/image/test/reftest/generic/moz-icon-blank-1-almostref.html
@@ -0,0 +1,2 @@
+<!-- this should draw an icon similar to a blank document but with writing on it -->
+<img src="moz-icon://.txt?size=16">
diff --git a/image/test/reftest/generic/moz-icon-blank-1-antiref.html b/image/test/reftest/generic/moz-icon-blank-1-antiref.html
new file mode 100644
index 0000000000..2631ff4018
--- /dev/null
+++ b/image/test/reftest/generic/moz-icon-blank-1-antiref.html
@@ -0,0 +1,2 @@
+<!-- this draws the icon for current directory on the c: drive on windows -->
+<img src="moz-icon:file:///C:/?size=16">
diff --git a/image/test/reftest/generic/moz-icon-blank-1-antiref2.html b/image/test/reftest/generic/moz-icon-blank-1-antiref2.html
new file mode 100644
index 0000000000..8553c81be0
--- /dev/null
+++ b/image/test/reftest/generic/moz-icon-blank-1-antiref2.html
@@ -0,0 +1,2 @@
+<!-- this draws the icon for the c: drive on windows -->
+<img src="moz-icon:file:///C://?size=16">
diff --git a/image/test/reftest/generic/moz-icon-blank-1-ref.html b/image/test/reftest/generic/moz-icon-blank-1-ref.html
new file mode 100644
index 0000000000..086d5af837
--- /dev/null
+++ b/image/test/reftest/generic/moz-icon-blank-1-ref.html
@@ -0,0 +1,2 @@
+<!-- this should draw a blank document icon -->
+<img src="moz-icon://bogus-unrecognized-icon.bogusunknown845?size=16">
diff --git a/image/test/reftest/generic/moz-icon-blank-1.html b/image/test/reftest/generic/moz-icon-blank-1.html
new file mode 100644
index 0000000000..2b52c96297
--- /dev/null
+++ b/image/test/reftest/generic/moz-icon-blank-1.html
@@ -0,0 +1,2 @@
+<!-- this should draw a blank document icon -->
+<img src="moz-icon://test?size=16&contentType=application/octet-stream">
diff --git a/image/test/reftest/generic/reftest.list b/image/test/reftest/generic/reftest.list
new file mode 100644
index 0000000000..6f236399ef
--- /dev/null
+++ b/image/test/reftest/generic/reftest.list
@@ -0,0 +1,6 @@
+HTTP == accept-image-catchall.html accept-image-catchall-ref.html
+skip-if(Android) != moz-icon-1.html about:blank
+== moz-icon-blank-1.html moz-icon-blank-1-ref.html
+skip-if(Android) != moz-icon-blank-1-ref.html moz-icon-blank-1-antiref.html
+skip-if(Android) != moz-icon-blank-1-ref.html moz-icon-blank-1-antiref2.html
+fuzzy-if(OSX,44-49,335-348) fuzzy-if(winWidget,64-140,45-191) == moz-icon-blank-1-almostref.html moz-icon-blank-1-ref.html
diff --git a/image/test/reftest/gif/1bit-255-trans.gif b/image/test/reftest/gif/1bit-255-trans.gif
new file mode 100644
index 0000000000..60273ba81d
--- /dev/null
+++ b/image/test/reftest/gif/1bit-255-trans.gif
Binary files differ
diff --git a/image/test/reftest/gif/1bit-255-trans.png b/image/test/reftest/gif/1bit-255-trans.png
new file mode 100644
index 0000000000..611480ac4c
--- /dev/null
+++ b/image/test/reftest/gif/1bit-255-trans.png
Binary files differ
diff --git a/image/test/reftest/gif/ImageDocument.css b/image/test/reftest/gif/ImageDocument.css
new file mode 100644
index 0000000000..b449810986
--- /dev/null
+++ b/image/test/reftest/gif/ImageDocument.css
@@ -0,0 +1,16 @@
+body {
+ background-image: url("chrome://global/skin/media/imagedoc-darknoise.png");
+ margin: 0;
+}
+
+body > :first-child {
+ display: block;
+ position: absolute;
+ margin: auto;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background: hsl(0,0%,90%) url("chrome://global/skin/media/imagedoc-lightnoise.png");
+ color: #222;
+}
diff --git a/image/test/reftest/gif/animation1a.gif b/image/test/reftest/gif/animation1a.gif
new file mode 100644
index 0000000000..d328276545
--- /dev/null
+++ b/image/test/reftest/gif/animation1a.gif
Binary files differ
diff --git a/image/test/reftest/gif/animation2a-finalframe.gif b/image/test/reftest/gif/animation2a-finalframe.gif
new file mode 100644
index 0000000000..8d9c4aaf7d
--- /dev/null
+++ b/image/test/reftest/gif/animation2a-finalframe.gif
Binary files differ
diff --git a/image/test/reftest/gif/animation2a.gif b/image/test/reftest/gif/animation2a.gif
new file mode 100644
index 0000000000..07abf8d986
--- /dev/null
+++ b/image/test/reftest/gif/animation2a.gif
Binary files differ
diff --git a/image/test/reftest/gif/blue.gif b/image/test/reftest/gif/blue.gif
new file mode 100644
index 0000000000..f9dbeeea8e
--- /dev/null
+++ b/image/test/reftest/gif/blue.gif
Binary files differ
diff --git a/image/test/reftest/gif/comment.gif b/image/test/reftest/gif/comment.gif
new file mode 100644
index 0000000000..255cceb418
--- /dev/null
+++ b/image/test/reftest/gif/comment.gif
Binary files differ
diff --git a/image/test/reftest/gif/comment.png b/image/test/reftest/gif/comment.png
new file mode 100644
index 0000000000..89394ba186
--- /dev/null
+++ b/image/test/reftest/gif/comment.png
Binary files differ
diff --git a/image/test/reftest/gif/delaytest.html b/image/test/reftest/gif/delaytest.html
new file mode 100644
index 0000000000..265a201ab5
--- /dev/null
+++ b/image/test/reftest/gif/delaytest.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Delayed image reftest wrapper</title>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img id="image1" alt=" ">
+<script>
+
+window.addEventListener("MozReftestInvalidate", reftestInvalidateListener);
+
+// This loads a externally specified image, forces a draw (in case of
+// decode-on-draw), waits 100ms, and then triggers the reftest snapshot.
+// This allows the animation on the page to complete.
+//
+// Use as "delaytest.html?animation.png"
+//
+
+// Get the image URL from our URL
+var imgURL = document.location.search.substr(1);
+
+// Load the image
+var img = document.images[0];
+img.src = imgURL;
+img.onload = forceDecode;
+
+let decodeComplete = false;
+let gotReftestInvalidate = false;
+
+function forceDecode() {
+ img.decode().then(function() {
+ decodeComplete = true;
+ maybeStartTimer();
+ }, function() {
+ decodeComplete = true;
+ maybeStartTimer();
+ });
+}
+
+function reftestInvalidateListener() {
+ gotReftestInvalidate = true;
+ maybeStartTimer();
+}
+
+function maybeStartTimer() {
+ if (decodeComplete && gotReftestInvalidate) {
+ startTimer();
+ }
+}
+
+function startTimer() {
+ const delay = 500;
+ setTimeout("document.documentElement.className = '';", delay);
+}
+</script>
+</body>
+</html>
diff --git a/image/test/reftest/gif/in-colormap-trans.gif b/image/test/reftest/gif/in-colormap-trans.gif
new file mode 100644
index 0000000000..48f5c7caf1
--- /dev/null
+++ b/image/test/reftest/gif/in-colormap-trans.gif
Binary files differ
diff --git a/image/test/reftest/gif/in-colormap-trans.png b/image/test/reftest/gif/in-colormap-trans.png
new file mode 100644
index 0000000000..08761dfe41
--- /dev/null
+++ b/image/test/reftest/gif/in-colormap-trans.png
Binary files differ
diff --git a/image/test/reftest/gif/one-color-offset-ref.gif b/image/test/reftest/gif/one-color-offset-ref.gif
new file mode 100644
index 0000000000..14a59ff477
--- /dev/null
+++ b/image/test/reftest/gif/one-color-offset-ref.gif
Binary files differ
diff --git a/image/test/reftest/gif/one-color-offset.gif b/image/test/reftest/gif/one-color-offset.gif
new file mode 100644
index 0000000000..e6d7c49322
--- /dev/null
+++ b/image/test/reftest/gif/one-color-offset.gif
Binary files differ
diff --git a/image/test/reftest/gif/one-pixel-no-image-data-ref.html b/image/test/reftest/gif/one-pixel-no-image-data-ref.html
new file mode 100644
index 0000000000..b23c11dc1b
--- /dev/null
+++ b/image/test/reftest/gif/one-pixel-no-image-data-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+html{
+background-color:black;
+}
+div {
+ width: 200px;
+ height: 200px;
+}
+</style>
+<div></div>
diff --git a/image/test/reftest/gif/one-pixel-no-image-data.html b/image/test/reftest/gif/one-pixel-no-image-data.html
new file mode 100644
index 0000000000..e09e90bd8b
--- /dev/null
+++ b/image/test/reftest/gif/one-pixel-no-image-data.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+html{
+background-color:black;
+}
+div {
+ width: 200px;
+ height: 200px;
+}
+</style>
+<div style="background-image:url(data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=)"></div>
diff --git a/image/test/reftest/gif/out-of-colormap-trans.gif b/image/test/reftest/gif/out-of-colormap-trans.gif
new file mode 100644
index 0000000000..17e747c9b2
--- /dev/null
+++ b/image/test/reftest/gif/out-of-colormap-trans.gif
Binary files differ
diff --git a/image/test/reftest/gif/out-of-colormap-trans.png b/image/test/reftest/gif/out-of-colormap-trans.png
new file mode 100644
index 0000000000..8d3eb581a2
--- /dev/null
+++ b/image/test/reftest/gif/out-of-colormap-trans.png
Binary files differ
diff --git a/image/test/reftest/gif/red.gif b/image/test/reftest/gif/red.gif
new file mode 100644
index 0000000000..d3c32bae25
--- /dev/null
+++ b/image/test/reftest/gif/red.gif
Binary files differ
diff --git a/image/test/reftest/gif/reftest.list b/image/test/reftest/gif/reftest.list
new file mode 100644
index 0000000000..1e44a83931
--- /dev/null
+++ b/image/test/reftest/gif/reftest.list
@@ -0,0 +1,32 @@
+# GIF tests
+
+# tests for bug 519589
+== 1bit-255-trans.gif 1bit-255-trans.png
+== in-colormap-trans.gif in-colormap-trans.png
+== out-of-colormap-trans.gif out-of-colormap-trans.png
+
+# a GIF file that uses the comment extension
+== comment.gif comment.png
+
+# a GIF file with a background smaller than the size of the canvas
+== small-background-size.gif small-background-size-ref.gif
+== small-background-size-2.gif small-background-size-2-ref.gif
+
+# a transparent gif that disposes previous frames with clear; we must properly
+# clear each frame to pass.
+== delaytest.html?transparent-animation.gif transparent-animation-finalframe.html
+
+# test for bug 641198
+skip == test_bug641198.html animation2a-finalframe.gif # Disabled; see bug 1120144.
+
+# Bug 1062886: a gif with a single color and an offset
+== one-color-offset.gif one-color-offset-ref.gif
+
+# Bug 1068230
+fuzzy-if(Android,0-1,0-8) == tile-transform.html tile-transform-ref.html
+
+# Bug 1234077
+== truncated-framerect.html truncated-framerect-ref.html
+
+# Bug 1801397
+== one-pixel-no-image-data.html one-pixel-no-image-data-ref.html
diff --git a/image/test/reftest/gif/small-background-size-2-ref.gif b/image/test/reftest/gif/small-background-size-2-ref.gif
new file mode 100644
index 0000000000..b513c41aa2
--- /dev/null
+++ b/image/test/reftest/gif/small-background-size-2-ref.gif
Binary files differ
diff --git a/image/test/reftest/gif/small-background-size-2.gif b/image/test/reftest/gif/small-background-size-2.gif
new file mode 100644
index 0000000000..a5e2147678
--- /dev/null
+++ b/image/test/reftest/gif/small-background-size-2.gif
Binary files differ
diff --git a/image/test/reftest/gif/small-background-size-ref.gif b/image/test/reftest/gif/small-background-size-ref.gif
new file mode 100644
index 0000000000..1b656ce439
--- /dev/null
+++ b/image/test/reftest/gif/small-background-size-ref.gif
Binary files differ
diff --git a/image/test/reftest/gif/small-background-size.gif b/image/test/reftest/gif/small-background-size.gif
new file mode 100644
index 0000000000..8185eb71e8
--- /dev/null
+++ b/image/test/reftest/gif/small-background-size.gif
Binary files differ
diff --git a/image/test/reftest/gif/test_bug641198.html b/image/test/reftest/gif/test_bug641198.html
new file mode 100644
index 0000000000..46bdb0d47c
--- /dev/null
+++ b/image/test/reftest/gif/test_bug641198.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Test for bug 641198</title>
+<link rel="stylesheet" href="ImageDocument.css">
+<style type="text/css" media=screen>
+ a.animated1 {
+ display: block;
+ width: 40px;
+ height: 40px;
+ background: url("animation1a.gif") no-repeat 0 0;
+ }
+
+ a.animated1 span {
+ position: absolute;
+ top: -999em;
+ }
+
+ a.animated2 {
+ display: block;
+ width: 40px;
+ height: 40px;
+ background: url("animation2a.gif") no-repeat 0 0;
+ }
+
+ a.animated2 span {
+ position: absolute;
+ top: -999em;
+ }
+</style>
+</head>
+<body onload="doTimeout()">
+
+<a id="animated" href="#" title="Animated"><span>Animated</span></a>
+
+<script>
+// We check whether changing the class will lead to the animation being
+// run from the beginning, even if the animation was already shown
+// before.
+var counter = 0;
+function doTimeout() {
+ if (counter == 4) {
+ document.documentElement.className = '';
+ } else {
+ document.getElementById("animated").setAttribute("class", "animated" + ((counter % 2)+1));
+ setTimeout(doTimeout, counter == 3 ? 500 : 250); // Wait a bit more for the last one, to prevent oranges
+ }
+ counter++;
+}
+</script>
+</body>
+</html>
+
diff --git a/image/test/reftest/gif/tile-transform-ref.html b/image/test/reftest/gif/tile-transform-ref.html
new file mode 100644
index 0000000000..5dac1a5bdf
--- /dev/null
+++ b/image/test/reftest/gif/tile-transform-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1068230
+-->
+<html>
+<head>
+ <title>Intermediate surface should be transformed correctly when tiling an image</title>
+</head>
+<body>
+<button style="margin: 10px; padding: 10px; border: none; background: url('tiletest-ref.png');"></button>
+</body>
+</html>
diff --git a/image/test/reftest/gif/tile-transform.html b/image/test/reftest/gif/tile-transform.html
new file mode 100644
index 0000000000..541ae6bbc4
--- /dev/null
+++ b/image/test/reftest/gif/tile-transform.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1068230
+-->
+<html>
+<head>
+ <title>Intermediate surface should be transformed correctly when tiling an image</title>
+</head>
+<body>
+<button style="margin: 10px; padding: 10px; border: none; background: url('tiletest.gif');"></button>
+</body>
+</html>
diff --git a/image/test/reftest/gif/tiletest-ref.png b/image/test/reftest/gif/tiletest-ref.png
new file mode 100644
index 0000000000..b493899cc8
--- /dev/null
+++ b/image/test/reftest/gif/tiletest-ref.png
Binary files differ
diff --git a/image/test/reftest/gif/tiletest.gif b/image/test/reftest/gif/tiletest.gif
new file mode 100644
index 0000000000..7a04c9654a
--- /dev/null
+++ b/image/test/reftest/gif/tiletest.gif
Binary files differ
diff --git a/image/test/reftest/gif/transparent-animation-finalframe.gif b/image/test/reftest/gif/transparent-animation-finalframe.gif
new file mode 100644
index 0000000000..a55f92a813
--- /dev/null
+++ b/image/test/reftest/gif/transparent-animation-finalframe.gif
Binary files differ
diff --git a/image/test/reftest/gif/transparent-animation-finalframe.html b/image/test/reftest/gif/transparent-animation-finalframe.html
new file mode 100644
index 0000000000..6f160d1b7c
--- /dev/null
+++ b/image/test/reftest/gif/transparent-animation-finalframe.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<img src="transparent-animation-finalframe.gif">
+</body>
+</html>
diff --git a/image/test/reftest/gif/transparent-animation.gif b/image/test/reftest/gif/transparent-animation.gif
new file mode 100644
index 0000000000..b2895487bd
--- /dev/null
+++ b/image/test/reftest/gif/transparent-animation.gif
Binary files differ
diff --git a/image/test/reftest/gif/truncated-framerect-interlaced-ref.gif b/image/test/reftest/gif/truncated-framerect-interlaced-ref.gif
new file mode 100644
index 0000000000..ca9bf2fa71
--- /dev/null
+++ b/image/test/reftest/gif/truncated-framerect-interlaced-ref.gif
Binary files differ
diff --git a/image/test/reftest/gif/truncated-framerect-interlaced.gif b/image/test/reftest/gif/truncated-framerect-interlaced.gif
new file mode 100644
index 0000000000..59709898bd
--- /dev/null
+++ b/image/test/reftest/gif/truncated-framerect-interlaced.gif
Binary files differ
diff --git a/image/test/reftest/gif/truncated-framerect-ref.gif b/image/test/reftest/gif/truncated-framerect-ref.gif
new file mode 100644
index 0000000000..ab79a455b0
--- /dev/null
+++ b/image/test/reftest/gif/truncated-framerect-ref.gif
Binary files differ
diff --git a/image/test/reftest/gif/truncated-framerect-ref.html b/image/test/reftest/gif/truncated-framerect-ref.html
new file mode 100644
index 0000000000..ef48b8a192
--- /dev/null
+++ b/image/test/reftest/gif/truncated-framerect-ref.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html>
+ <head>
+ <title>Bug 1234077 - Make sure GIFs still render correctly with a truncated frameRect</title>
+ <style type="text/css">
+ div, img {
+ padding: 0;
+ margin: 0;
+ border: 0;
+ overflow: hidden;
+ width: 200px;
+ height: 200px;
+ }
+
+ div img {
+ margin: 136px 0 0 136px;
+ }
+ </style>
+ </head>
+ <body>
+ <img src="truncated-framerect-interlaced-ref.gif" />
+
+ <div>
+ <img src="truncated-framerect-ref.gif" />
+ </div>
+
+ <div>
+ <img src="truncated-framerect-interlaced-ref.gif" />
+ </div>
+ </body>
+</html>
diff --git a/image/test/reftest/gif/truncated-framerect.gif b/image/test/reftest/gif/truncated-framerect.gif
new file mode 100644
index 0000000000..8febb2a748
--- /dev/null
+++ b/image/test/reftest/gif/truncated-framerect.gif
Binary files differ
diff --git a/image/test/reftest/gif/truncated-framerect.html b/image/test/reftest/gif/truncated-framerect.html
new file mode 100644
index 0000000000..c1c5df6538
--- /dev/null
+++ b/image/test/reftest/gif/truncated-framerect.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html>
+ <head>
+ <title>Bug 1234077 - Make sure GIFs still render correctly with a truncated frameRect</title>
+ <style type="text/css">
+ div, img {
+ padding: 0;
+ margin: 0;
+ border: 0;
+ width: 200px;
+ height: 200px;
+ }
+ </style>
+ </head>
+ <body>
+ <img src="truncated-framerect-ref.gif" />
+
+ <div>
+ <img src="truncated-framerect.gif" />
+ </div>
+
+ <div>
+ <img src="truncated-framerect-interlaced.gif" />
+ </div>
+ </body>
+</html>
diff --git a/image/test/reftest/ico/cur/pointer.cur b/image/test/reftest/ico/cur/pointer.cur
new file mode 100644
index 0000000000..025ebaed1f
--- /dev/null
+++ b/image/test/reftest/ico/cur/pointer.cur
Binary files differ
diff --git a/image/test/reftest/ico/cur/pointer.png b/image/test/reftest/ico/cur/pointer.png
new file mode 100644
index 0000000000..84ad8f3fbd
--- /dev/null
+++ b/image/test/reftest/ico/cur/pointer.png
Binary files differ
diff --git a/image/test/reftest/ico/cur/reftest.list b/image/test/reftest/ico/cur/reftest.list
new file mode 100644
index 0000000000..635136506b
--- /dev/null
+++ b/image/test/reftest/ico/cur/reftest.list
@@ -0,0 +1,4 @@
+# ICO BMP and PNG mixed tests
+
+== wrapper.html?pointer.cur wrapper.html?pointer.png
+
diff --git a/image/test/reftest/ico/cur/wrapper.html b/image/test/reftest/ico/cur/wrapper.html
new file mode 100644
index 0000000000..45b5167754
--- /dev/null
+++ b/image/test/reftest/ico/cur/wrapper.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Image reftest wrapper</title>
+<style type="text/css">
+ #image1 { background-color: rgb(10, 100, 250); }
+</style>
+<script>
+ // The image is loaded async after the page loads
+ // wait for it to finish loading
+ function onImageLoad() {
+ document.documentElement.removeAttribute("class");
+ };
+</script>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img id="image1" alt=" ">
+<script>
+ // Use as "wrapper.html?image.png
+ var imgURL = document.location.search.substr(1);
+ document.images[0].onload = onImageLoad;
+ document.images[0].onerror = onImageLoad;
+ document.images[0].src = imgURL;
+</script>
+</body>
+</html>
+
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-not-square-transparent-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-not-square-transparent-1bpp.ico
new file mode 100644
index 0000000000..0f51d504af
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-not-square-transparent-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-not-square-transparent-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-not-square-transparent-1bpp.png
new file mode 100644
index 0000000000..152b30d716
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-not-square-transparent-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-partial-transparent-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-partial-transparent-1bpp.ico
new file mode 100644
index 0000000000..def2a4ece7
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-partial-transparent-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-partial-transparent-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-partial-transparent-1bpp.png
new file mode 100644
index 0000000000..064a68bb2e
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-partial-transparent-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-15x15-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-15x15-1bpp.ico
new file mode 100644
index 0000000000..b68cf0ef0d
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-15x15-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-15x15-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-15x15-1bpp.png
new file mode 100644
index 0000000000..956c78ece6
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-15x15-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-16x16-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-16x16-1bpp.ico
new file mode 100644
index 0000000000..d96a4a0e1d
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-16x16-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-16x16-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-16x16-1bpp.png
new file mode 100644
index 0000000000..90088351fa
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-16x16-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-17x17-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-17x17-1bpp.ico
new file mode 100644
index 0000000000..4f10ad13c0
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-17x17-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-17x17-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-17x17-1bpp.png
new file mode 100644
index 0000000000..9a294696c4
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-17x17-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-1x1-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-1x1-1bpp.ico
new file mode 100644
index 0000000000..5af8bef61a
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-1x1-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-1x1-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-1x1-1bpp.png
new file mode 100644
index 0000000000..7a07a124ea
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-1x1-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-256x256-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-256x256-1bpp.ico
new file mode 100644
index 0000000000..63d95e3b7c
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-256x256-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-256x256-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-256x256-1bpp.png
new file mode 100644
index 0000000000..0a23d8c8ee
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-256x256-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-2x2-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-2x2-1bpp.ico
new file mode 100644
index 0000000000..09c140f1b1
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-2x2-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-2x2-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-2x2-1bpp.png
new file mode 100644
index 0000000000..3b09f80769
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-2x2-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-31x31-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-31x31-1bpp.ico
new file mode 100644
index 0000000000..bbfc3165ab
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-31x31-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-31x31-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-31x31-1bpp.png
new file mode 100644
index 0000000000..d1fe6ddeee
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-31x31-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-32x32-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-32x32-1bpp.ico
new file mode 100644
index 0000000000..279ecb8358
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-32x32-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-32x32-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-32x32-1bpp.png
new file mode 100644
index 0000000000..078d3dc5d0
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-32x32-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-33x33-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-33x33-1bpp.ico
new file mode 100644
index 0000000000..fa1862c1ca
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-33x33-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-33x33-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-33x33-1bpp.png
new file mode 100644
index 0000000000..e64e12b2aa
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-33x33-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-3x3-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-3x3-1bpp.ico
new file mode 100644
index 0000000000..733b1f12bc
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-3x3-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-3x3-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-3x3-1bpp.png
new file mode 100644
index 0000000000..b8519a8749
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-3x3-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-4x4-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-4x4-1bpp.ico
new file mode 100644
index 0000000000..ba3097cecd
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-4x4-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-4x4-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-4x4-1bpp.png
new file mode 100644
index 0000000000..3977b54548
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-4x4-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-5x5-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-5x5-1bpp.ico
new file mode 100644
index 0000000000..52e32df27b
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-5x5-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-5x5-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-5x5-1bpp.png
new file mode 100644
index 0000000000..caa9246b67
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-5x5-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-6x6-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-6x6-1bpp.ico
new file mode 100644
index 0000000000..c29651400f
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-6x6-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-6x6-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-6x6-1bpp.png
new file mode 100644
index 0000000000..30e1b0249d
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-6x6-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-7x7-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-7x7-1bpp.ico
new file mode 100644
index 0000000000..8ce9915c44
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-7x7-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-7x7-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-7x7-1bpp.png
new file mode 100644
index 0000000000..9dbaae84cb
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-7x7-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-8x8-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-8x8-1bpp.ico
new file mode 100644
index 0000000000..485dff028a
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-8x8-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-8x8-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-8x8-1bpp.png
new file mode 100644
index 0000000000..2201388408
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-8x8-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-9x9-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-9x9-1bpp.ico
new file mode 100644
index 0000000000..38f34ec50a
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-9x9-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-size-9x9-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-9x9-1bpp.png
new file mode 100644
index 0000000000..7fe1b548b8
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-size-9x9-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-transparent-1bpp.ico b/image/test/reftest/ico/ico-bmp-1bpp/ico-transparent-1bpp.ico
new file mode 100644
index 0000000000..8e361306c5
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-transparent-1bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/ico-transparent-1bpp.png b/image/test/reftest/ico/ico-bmp-1bpp/ico-transparent-1bpp.png
new file mode 100644
index 0000000000..062152e3b1
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/ico-transparent-1bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-1bpp/reftest.list b/image/test/reftest/ico/ico-bmp-1bpp/reftest.list
new file mode 100644
index 0000000000..1b9ca1348a
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-1bpp/reftest.list
@@ -0,0 +1,23 @@
+# ICO BMP 1BPP tests
+
+# Images of various sizes
+== ico-size-1x1-1bpp.ico ico-size-1x1-1bpp.png
+== ico-size-2x2-1bpp.ico ico-size-2x2-1bpp.png
+== ico-size-3x3-1bpp.ico ico-size-3x3-1bpp.png
+== ico-size-4x4-1bpp.ico ico-size-4x4-1bpp.png
+== ico-size-5x5-1bpp.ico ico-size-5x5-1bpp.png
+== ico-size-6x6-1bpp.ico ico-size-6x6-1bpp.png
+== ico-size-7x7-1bpp.ico ico-size-7x7-1bpp.png
+== ico-size-8x8-1bpp.ico ico-size-8x8-1bpp.png
+== ico-size-9x9-1bpp.ico ico-size-9x9-1bpp.png
+== ico-size-15x15-1bpp.ico ico-size-15x15-1bpp.png
+== ico-size-16x16-1bpp.ico ico-size-16x16-1bpp.png
+== ico-size-17x17-1bpp.ico ico-size-17x17-1bpp.png
+== ico-size-31x31-1bpp.ico ico-size-31x31-1bpp.png
+== ico-size-32x32-1bpp.ico ico-size-32x32-1bpp.png
+== ico-size-33x33-1bpp.ico ico-size-33x33-1bpp.png
+== ico-size-256x256-1bpp.ico ico-size-256x256-1bpp.png
+== ico-partial-transparent-1bpp.ico ico-partial-transparent-1bpp.png
+== ico-transparent-1bpp.ico ico-transparent-1bpp.png
+== ico-not-square-transparent-1bpp.ico ico-not-square-transparent-1bpp.png
+
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-not-square-transparent-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-not-square-transparent-24bpp.ico
new file mode 100644
index 0000000000..16d6584ef8
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-not-square-transparent-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-not-square-transparent-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-not-square-transparent-24bpp.png
new file mode 100644
index 0000000000..a881048b96
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-not-square-transparent-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-partial-transparent-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-partial-transparent-24bpp.ico
new file mode 100644
index 0000000000..ab0dc4bce1
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-partial-transparent-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-partial-transparent-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-partial-transparent-24bpp.png
new file mode 100644
index 0000000000..0363210c74
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-partial-transparent-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-15x15-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-15x15-24bpp.ico
new file mode 100644
index 0000000000..8721b0d169
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-15x15-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-15x15-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-15x15-24bpp.png
new file mode 100644
index 0000000000..e1287430d0
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-15x15-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-16x16-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-16x16-24bpp.ico
new file mode 100644
index 0000000000..04e4736189
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-16x16-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-16x16-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-16x16-24bpp.png
new file mode 100644
index 0000000000..c04869e728
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-16x16-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-17x17-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-17x17-24bpp.ico
new file mode 100644
index 0000000000..308ccb7a61
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-17x17-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-17x17-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-17x17-24bpp.png
new file mode 100644
index 0000000000..00fb8e4f37
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-17x17-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-1x1-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-1x1-24bpp.ico
new file mode 100644
index 0000000000..e2bf90c093
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-1x1-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-1x1-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-1x1-24bpp.png
new file mode 100644
index 0000000000..c05f5fef89
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-1x1-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-256x256-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-256x256-24bpp.ico
new file mode 100644
index 0000000000..c3977400a4
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-256x256-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-256x256-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-256x256-24bpp.png
new file mode 100644
index 0000000000..84bfada761
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-256x256-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-2x2-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-2x2-24bpp.ico
new file mode 100644
index 0000000000..dba180a07a
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-2x2-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-2x2-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-2x2-24bpp.png
new file mode 100644
index 0000000000..e512d3f9b4
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-2x2-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-31x31-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-31x31-24bpp.ico
new file mode 100644
index 0000000000..aa67502f61
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-31x31-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-31x31-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-31x31-24bpp.png
new file mode 100644
index 0000000000..e4a8642514
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-31x31-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-32x32-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-32x32-24bpp.ico
new file mode 100644
index 0000000000..a85b871c5e
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-32x32-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-32x32-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-32x32-24bpp.png
new file mode 100644
index 0000000000..3a6fbe8ee9
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-32x32-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-33x33-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-33x33-24bpp.ico
new file mode 100644
index 0000000000..a5c49374de
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-33x33-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-33x33-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-33x33-24bpp.png
new file mode 100644
index 0000000000..72ef7eb636
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-33x33-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-3x3-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-3x3-24bpp.ico
new file mode 100644
index 0000000000..8a0b9433f4
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-3x3-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-3x3-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-3x3-24bpp.png
new file mode 100644
index 0000000000..cb42ec4f87
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-3x3-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-4x4-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-4x4-24bpp.ico
new file mode 100644
index 0000000000..feb3f11e16
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-4x4-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-4x4-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-4x4-24bpp.png
new file mode 100644
index 0000000000..e6afafd89a
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-4x4-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-5x5-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-5x5-24bpp.ico
new file mode 100644
index 0000000000..d607ca5724
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-5x5-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-5x5-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-5x5-24bpp.png
new file mode 100644
index 0000000000..a844aff76d
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-5x5-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-6x6-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-6x6-24bpp.ico
new file mode 100644
index 0000000000..62a231602c
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-6x6-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-6x6-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-6x6-24bpp.png
new file mode 100644
index 0000000000..415c2d9c6a
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-6x6-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-7x7-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-7x7-24bpp.ico
new file mode 100644
index 0000000000..d884ecfd77
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-7x7-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-7x7-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-7x7-24bpp.png
new file mode 100644
index 0000000000..ab2f892747
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-7x7-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-8x8-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-8x8-24bpp.ico
new file mode 100644
index 0000000000..782ae220df
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-8x8-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-8x8-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-8x8-24bpp.png
new file mode 100644
index 0000000000..fe2ff40a1d
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-8x8-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-9x9-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-9x9-24bpp.ico
new file mode 100644
index 0000000000..97992643b6
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-9x9-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-size-9x9-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-9x9-24bpp.png
new file mode 100644
index 0000000000..18ab4b25de
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-size-9x9-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-transparent-24bpp.ico b/image/test/reftest/ico/ico-bmp-24bpp/ico-transparent-24bpp.ico
new file mode 100644
index 0000000000..8e361306c5
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-transparent-24bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/ico-transparent-24bpp.png b/image/test/reftest/ico/ico-bmp-24bpp/ico-transparent-24bpp.png
new file mode 100644
index 0000000000..062152e3b1
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/ico-transparent-24bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-24bpp/reftest.list b/image/test/reftest/ico/ico-bmp-24bpp/reftest.list
new file mode 100644
index 0000000000..8772936603
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-24bpp/reftest.list
@@ -0,0 +1,23 @@
+# ICO BMP 24BPP tests
+
+# Images of various sizes
+== ico-size-1x1-24bpp.ico ico-size-1x1-24bpp.png
+== ico-size-2x2-24bpp.ico ico-size-2x2-24bpp.png
+== ico-size-3x3-24bpp.ico ico-size-3x3-24bpp.png
+== ico-size-4x4-24bpp.ico ico-size-4x4-24bpp.png
+== ico-size-5x5-24bpp.ico ico-size-5x5-24bpp.png
+== ico-size-6x6-24bpp.ico ico-size-6x6-24bpp.png
+== ico-size-7x7-24bpp.ico ico-size-7x7-24bpp.png
+== ico-size-8x8-24bpp.ico ico-size-8x8-24bpp.png
+== ico-size-9x9-24bpp.ico ico-size-9x9-24bpp.png
+== ico-size-15x15-24bpp.ico ico-size-15x15-24bpp.png
+== ico-size-16x16-24bpp.ico ico-size-16x16-24bpp.png
+== ico-size-17x17-24bpp.ico ico-size-17x17-24bpp.png
+== ico-size-31x31-24bpp.ico ico-size-31x31-24bpp.png
+== ico-size-32x32-24bpp.ico ico-size-32x32-24bpp.png
+== ico-size-33x33-24bpp.ico ico-size-33x33-24bpp.png
+== ico-size-256x256-24bpp.ico ico-size-256x256-24bpp.png
+== ico-partial-transparent-24bpp.ico ico-partial-transparent-24bpp.png
+== ico-transparent-24bpp.ico ico-transparent-24bpp.png
+== ico-not-square-transparent-24bpp.ico ico-not-square-transparent-24bpp.png
+
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-not-square-transparent-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-not-square-transparent-32bpp.ico
new file mode 100644
index 0000000000..dd0299c413
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-not-square-transparent-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-not-square-transparent-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-not-square-transparent-32bpp.png
new file mode 100644
index 0000000000..befc665552
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-not-square-transparent-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-partial-transparent-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-partial-transparent-32bpp.ico
new file mode 100644
index 0000000000..8ad62f7d0e
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-partial-transparent-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-partial-transparent-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-partial-transparent-32bpp.png
new file mode 100644
index 0000000000..226ad6494f
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-partial-transparent-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-15x15-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-15x15-32bpp.ico
new file mode 100644
index 0000000000..1f1b6b51ce
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-15x15-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-15x15-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-15x15-32bpp.png
new file mode 100644
index 0000000000..e1287430d0
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-15x15-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-16x16-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-16x16-32bpp.ico
new file mode 100644
index 0000000000..7a8f01529d
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-16x16-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-16x16-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-16x16-32bpp.png
new file mode 100644
index 0000000000..c04869e728
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-16x16-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-17x17-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-17x17-32bpp.ico
new file mode 100644
index 0000000000..b92860be4f
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-17x17-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-17x17-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-17x17-32bpp.png
new file mode 100644
index 0000000000..00fb8e4f37
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-17x17-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-1x1-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-1x1-32bpp.ico
new file mode 100644
index 0000000000..5ad60c575c
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-1x1-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-1x1-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-1x1-32bpp.png
new file mode 100644
index 0000000000..c05f5fef89
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-1x1-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-256x256-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-256x256-32bpp.ico
new file mode 100644
index 0000000000..f8b530ef0b
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-256x256-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-256x256-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-256x256-32bpp.png
new file mode 100644
index 0000000000..84bfada761
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-256x256-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-2x2-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-2x2-32bpp.ico
new file mode 100644
index 0000000000..e5b2bf7e76
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-2x2-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-2x2-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-2x2-32bpp.png
new file mode 100644
index 0000000000..e512d3f9b4
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-2x2-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-31x31-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-31x31-32bpp.ico
new file mode 100644
index 0000000000..ddcbde85f4
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-31x31-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-31x31-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-31x31-32bpp.png
new file mode 100644
index 0000000000..e4a8642514
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-31x31-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-32x32-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-32x32-32bpp.ico
new file mode 100644
index 0000000000..a89c016485
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-32x32-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-32x32-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-32x32-32bpp.png
new file mode 100644
index 0000000000..3a6fbe8ee9
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-32x32-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-33x33-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-33x33-32bpp.ico
new file mode 100644
index 0000000000..cda9133f8b
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-33x33-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-33x33-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-33x33-32bpp.png
new file mode 100644
index 0000000000..72ef7eb636
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-33x33-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-3x3-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-3x3-32bpp.ico
new file mode 100644
index 0000000000..3894ccf212
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-3x3-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-3x3-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-3x3-32bpp.png
new file mode 100644
index 0000000000..cb42ec4f87
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-3x3-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-4x4-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-4x4-32bpp.ico
new file mode 100644
index 0000000000..828494c668
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-4x4-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-4x4-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-4x4-32bpp.png
new file mode 100644
index 0000000000..e6afafd89a
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-4x4-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-5x5-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-5x5-32bpp.ico
new file mode 100644
index 0000000000..4f0a2bcc72
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-5x5-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-5x5-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-5x5-32bpp.png
new file mode 100644
index 0000000000..a844aff76d
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-5x5-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-6x6-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-6x6-32bpp.ico
new file mode 100644
index 0000000000..5524769e60
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-6x6-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-6x6-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-6x6-32bpp.png
new file mode 100644
index 0000000000..415c2d9c6a
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-6x6-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-7x7-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-7x7-32bpp.ico
new file mode 100644
index 0000000000..6aeebb898d
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-7x7-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-7x7-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-7x7-32bpp.png
new file mode 100644
index 0000000000..ab2f892747
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-7x7-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-8x8-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-8x8-32bpp.ico
new file mode 100644
index 0000000000..824c744a20
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-8x8-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-8x8-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-8x8-32bpp.png
new file mode 100644
index 0000000000..fe2ff40a1d
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-8x8-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-9x9-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-9x9-32bpp.ico
new file mode 100644
index 0000000000..cf1f6e9c88
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-9x9-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-size-9x9-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-9x9-32bpp.png
new file mode 100644
index 0000000000..18ab4b25de
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-size-9x9-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-transparent-32bpp.ico b/image/test/reftest/ico/ico-bmp-32bpp/ico-transparent-32bpp.ico
new file mode 100644
index 0000000000..151b7cb361
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-transparent-32bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/ico-transparent-32bpp.png b/image/test/reftest/ico/ico-bmp-32bpp/ico-transparent-32bpp.png
new file mode 100644
index 0000000000..062152e3b1
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/ico-transparent-32bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-32bpp/reftest.list b/image/test/reftest/ico/ico-bmp-32bpp/reftest.list
new file mode 100644
index 0000000000..e05355a2bf
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-32bpp/reftest.list
@@ -0,0 +1,22 @@
+# ICO BMP 32BPP tests
+
+# Images of various sizes
+== ico-size-1x1-32bpp.ico ico-size-1x1-32bpp.png
+== ico-size-2x2-32bpp.ico ico-size-2x2-32bpp.png
+== ico-size-3x3-32bpp.ico ico-size-3x3-32bpp.png
+== ico-size-4x4-32bpp.ico ico-size-4x4-32bpp.png
+== ico-size-5x5-32bpp.ico ico-size-5x5-32bpp.png
+== ico-size-6x6-32bpp.ico ico-size-6x6-32bpp.png
+== ico-size-7x7-32bpp.ico ico-size-7x7-32bpp.png
+== ico-size-8x8-32bpp.ico ico-size-8x8-32bpp.png
+== ico-size-9x9-32bpp.ico ico-size-9x9-32bpp.png
+== ico-size-15x15-32bpp.ico ico-size-15x15-32bpp.png
+== ico-size-16x16-32bpp.ico ico-size-16x16-32bpp.png
+== ico-size-17x17-32bpp.ico ico-size-17x17-32bpp.png
+== ico-size-31x31-32bpp.ico ico-size-31x31-32bpp.png
+== ico-size-32x32-32bpp.ico ico-size-32x32-32bpp.png
+== ico-size-33x33-32bpp.ico ico-size-33x33-32bpp.png
+== ico-size-256x256-32bpp.ico ico-size-256x256-32bpp.png
+== ico-partial-transparent-32bpp.ico ico-partial-transparent-32bpp.png
+== ico-transparent-32bpp.ico ico-transparent-32bpp.png
+== ico-not-square-transparent-32bpp.ico ico-not-square-transparent-32bpp.png
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-not-square-transparent-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-not-square-transparent-4bpp.ico
new file mode 100644
index 0000000000..d502d2ef6b
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-not-square-transparent-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-not-square-transparent-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-not-square-transparent-4bpp.png
new file mode 100644
index 0000000000..3e556ad293
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-not-square-transparent-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-partial-transparent-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-partial-transparent-4bpp.ico
new file mode 100644
index 0000000000..7bd3b8a69f
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-partial-transparent-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-partial-transparent-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-partial-transparent-4bpp.png
new file mode 100644
index 0000000000..9ff0ce41f7
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-partial-transparent-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-15x15-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-15x15-4bpp.ico
new file mode 100644
index 0000000000..de5c49e2a6
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-15x15-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-15x15-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-15x15-4bpp.png
new file mode 100644
index 0000000000..5d4a3f9534
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-15x15-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-16x16-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-16x16-4bpp.ico
new file mode 100644
index 0000000000..b856b3f376
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-16x16-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-16x16-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-16x16-4bpp.png
new file mode 100644
index 0000000000..d45d63f539
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-16x16-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-17x17-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-17x17-4bpp.ico
new file mode 100644
index 0000000000..44e055d2f7
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-17x17-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-17x17-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-17x17-4bpp.png
new file mode 100644
index 0000000000..bf48903299
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-17x17-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-1x1-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-1x1-4bpp.ico
new file mode 100644
index 0000000000..fd46c328d5
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-1x1-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-1x1-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-1x1-4bpp.png
new file mode 100644
index 0000000000..d41dd645b7
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-1x1-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-256x256-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-256x256-4bpp.ico
new file mode 100644
index 0000000000..6d28edaa8f
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-256x256-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-256x256-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-256x256-4bpp.png
new file mode 100644
index 0000000000..3acdef8303
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-256x256-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-2x2-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-2x2-4bpp.ico
new file mode 100644
index 0000000000..7dc4afde68
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-2x2-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-2x2-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-2x2-4bpp.png
new file mode 100644
index 0000000000..b2d6050415
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-2x2-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-31x31-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-31x31-4bpp.ico
new file mode 100644
index 0000000000..0471332d6b
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-31x31-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-31x31-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-31x31-4bpp.png
new file mode 100644
index 0000000000..cb12a3448d
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-31x31-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-32x32-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-32x32-4bpp.ico
new file mode 100644
index 0000000000..ef005dc5bf
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-32x32-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-32x32-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-32x32-4bpp.png
new file mode 100644
index 0000000000..58d867d120
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-32x32-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-33x33-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-33x33-4bpp.ico
new file mode 100644
index 0000000000..4c71963a49
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-33x33-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-33x33-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-33x33-4bpp.png
new file mode 100644
index 0000000000..064fde198c
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-33x33-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-3x3-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-3x3-4bpp.ico
new file mode 100644
index 0000000000..aaa6350e96
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-3x3-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-3x3-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-3x3-4bpp.png
new file mode 100644
index 0000000000..e34114d5c9
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-3x3-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-4x4-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-4x4-4bpp.ico
new file mode 100644
index 0000000000..767bebed41
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-4x4-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-4x4-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-4x4-4bpp.png
new file mode 100644
index 0000000000..3efa555620
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-4x4-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-5x5-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-5x5-4bpp.ico
new file mode 100644
index 0000000000..309b6fe5b0
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-5x5-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-5x5-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-5x5-4bpp.png
new file mode 100644
index 0000000000..02ebf57a51
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-5x5-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-6x6-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-6x6-4bpp.ico
new file mode 100644
index 0000000000..255fda6a84
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-6x6-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-6x6-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-6x6-4bpp.png
new file mode 100644
index 0000000000..1f5769d09c
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-6x6-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-7x7-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-7x7-4bpp.ico
new file mode 100644
index 0000000000..1a39634526
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-7x7-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-7x7-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-7x7-4bpp.png
new file mode 100644
index 0000000000..59a1b98b52
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-7x7-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-8x8-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-8x8-4bpp.ico
new file mode 100644
index 0000000000..40bc9f8937
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-8x8-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-8x8-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-8x8-4bpp.png
new file mode 100644
index 0000000000..cf44f59676
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-8x8-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-9x9-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-9x9-4bpp.ico
new file mode 100644
index 0000000000..bda12f32b9
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-9x9-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-size-9x9-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-9x9-4bpp.png
new file mode 100644
index 0000000000..2e07364135
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-size-9x9-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-transparent-4bpp.ico b/image/test/reftest/ico/ico-bmp-4bpp/ico-transparent-4bpp.ico
new file mode 100644
index 0000000000..8e361306c5
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-transparent-4bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/ico-transparent-4bpp.png b/image/test/reftest/ico/ico-bmp-4bpp/ico-transparent-4bpp.png
new file mode 100644
index 0000000000..062152e3b1
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/ico-transparent-4bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-4bpp/reftest.list b/image/test/reftest/ico/ico-bmp-4bpp/reftest.list
new file mode 100644
index 0000000000..6caac4ac86
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-4bpp/reftest.list
@@ -0,0 +1,23 @@
+# ICO BMP 4BPP tests
+
+# Images of various sizes
+== ico-size-1x1-4bpp.ico ico-size-1x1-4bpp.png
+== ico-size-2x2-4bpp.ico ico-size-2x2-4bpp.png
+== ico-size-3x3-4bpp.ico ico-size-3x3-4bpp.png
+== ico-size-4x4-4bpp.ico ico-size-4x4-4bpp.png
+== ico-size-5x5-4bpp.ico ico-size-5x5-4bpp.png
+== ico-size-6x6-4bpp.ico ico-size-6x6-4bpp.png
+== ico-size-7x7-4bpp.ico ico-size-7x7-4bpp.png
+== ico-size-8x8-4bpp.ico ico-size-8x8-4bpp.png
+== ico-size-9x9-4bpp.ico ico-size-9x9-4bpp.png
+== ico-size-15x15-4bpp.ico ico-size-15x15-4bpp.png
+== ico-size-16x16-4bpp.ico ico-size-16x16-4bpp.png
+== ico-size-17x17-4bpp.ico ico-size-17x17-4bpp.png
+== ico-size-31x31-4bpp.ico ico-size-31x31-4bpp.png
+== ico-size-32x32-4bpp.ico ico-size-32x32-4bpp.png
+== ico-size-33x33-4bpp.ico ico-size-33x33-4bpp.png
+== ico-size-256x256-4bpp.ico ico-size-256x256-4bpp.png
+== ico-partial-transparent-4bpp.ico ico-partial-transparent-4bpp.png
+== ico-transparent-4bpp.ico ico-transparent-4bpp.png
+== ico-not-square-transparent-4bpp.ico ico-not-square-transparent-4bpp.png
+
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-not-square-transparent-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-not-square-transparent-8bpp.ico
new file mode 100644
index 0000000000..d28b9a04ec
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-not-square-transparent-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-not-square-transparent-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-not-square-transparent-8bpp.png
new file mode 100644
index 0000000000..36a4eb5122
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-not-square-transparent-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-partial-transparent-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-partial-transparent-8bpp.ico
new file mode 100644
index 0000000000..9074caa401
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-partial-transparent-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-partial-transparent-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-partial-transparent-8bpp.png
new file mode 100644
index 0000000000..6f990f2572
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-partial-transparent-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-15x15-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-15x15-8bpp.ico
new file mode 100644
index 0000000000..f3f3a13530
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-15x15-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-15x15-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-15x15-8bpp.png
new file mode 100644
index 0000000000..e1287430d0
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-15x15-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-16x16-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-16x16-8bpp.ico
new file mode 100644
index 0000000000..24c20e23ec
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-16x16-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-16x16-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-16x16-8bpp.png
new file mode 100644
index 0000000000..2e66b2e5f9
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-16x16-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-17x17-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-17x17-8bpp.ico
new file mode 100644
index 0000000000..7fa66b9b21
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-17x17-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-17x17-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-17x17-8bpp.png
new file mode 100644
index 0000000000..4d11d7561c
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-17x17-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-1x1-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-1x1-8bpp.ico
new file mode 100644
index 0000000000..3cf3320eae
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-1x1-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-1x1-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-1x1-8bpp.png
new file mode 100644
index 0000000000..c05f5fef89
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-1x1-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-256x256-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-256x256-8bpp.ico
new file mode 100644
index 0000000000..524b6f7c8e
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-256x256-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-256x256-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-256x256-8bpp.png
new file mode 100644
index 0000000000..f367468c95
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-256x256-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-2x2-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-2x2-8bpp.ico
new file mode 100644
index 0000000000..95d8375a00
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-2x2-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-2x2-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-2x2-8bpp.png
new file mode 100644
index 0000000000..e512d3f9b4
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-2x2-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-31x31-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-31x31-8bpp.ico
new file mode 100644
index 0000000000..7806754474
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-31x31-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-31x31-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-31x31-8bpp.png
new file mode 100644
index 0000000000..84bf61078c
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-31x31-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-32x32-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-32x32-8bpp.ico
new file mode 100644
index 0000000000..d21cc5b967
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-32x32-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-32x32-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-32x32-8bpp.png
new file mode 100644
index 0000000000..349fd4df24
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-32x32-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-33x33-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-33x33-8bpp.ico
new file mode 100644
index 0000000000..1b419b2632
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-33x33-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-33x33-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-33x33-8bpp.png
new file mode 100644
index 0000000000..a4c100649a
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-33x33-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-3x3-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-3x3-8bpp.ico
new file mode 100644
index 0000000000..869f74fcdc
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-3x3-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-3x3-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-3x3-8bpp.png
new file mode 100644
index 0000000000..cb42ec4f87
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-3x3-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-4x4-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-4x4-8bpp.ico
new file mode 100644
index 0000000000..3967563727
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-4x4-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-4x4-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-4x4-8bpp.png
new file mode 100644
index 0000000000..e6afafd89a
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-4x4-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-5x5-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-5x5-8bpp.ico
new file mode 100644
index 0000000000..92814e3661
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-5x5-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-5x5-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-5x5-8bpp.png
new file mode 100644
index 0000000000..a844aff76d
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-5x5-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-6x6-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-6x6-8bpp.ico
new file mode 100644
index 0000000000..1af478a8a8
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-6x6-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-6x6-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-6x6-8bpp.png
new file mode 100644
index 0000000000..415c2d9c6a
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-6x6-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-7x7-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-7x7-8bpp.ico
new file mode 100644
index 0000000000..1c70820ebd
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-7x7-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-7x7-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-7x7-8bpp.png
new file mode 100644
index 0000000000..ab2f892747
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-7x7-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-8x8-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-8x8-8bpp.ico
new file mode 100644
index 0000000000..782ae220df
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-8x8-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-8x8-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-8x8-8bpp.png
new file mode 100644
index 0000000000..fe2ff40a1d
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-8x8-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-9x9-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-9x9-8bpp.ico
new file mode 100644
index 0000000000..6825372b4a
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-9x9-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-size-9x9-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-9x9-8bpp.png
new file mode 100644
index 0000000000..18ab4b25de
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-size-9x9-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-transparent-8bpp.ico b/image/test/reftest/ico/ico-bmp-8bpp/ico-transparent-8bpp.ico
new file mode 100644
index 0000000000..8e361306c5
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-transparent-8bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/ico-transparent-8bpp.png b/image/test/reftest/ico/ico-bmp-8bpp/ico-transparent-8bpp.png
new file mode 100644
index 0000000000..062152e3b1
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/ico-transparent-8bpp.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-8bpp/reftest.list b/image/test/reftest/ico/ico-bmp-8bpp/reftest.list
new file mode 100644
index 0000000000..5a6b543238
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-8bpp/reftest.list
@@ -0,0 +1,23 @@
+# ICO BMP 8BPP tests
+
+# Images of various sizes
+== ico-size-1x1-8bpp.ico ico-size-1x1-8bpp.png
+== ico-size-2x2-8bpp.ico ico-size-2x2-8bpp.png
+== ico-size-3x3-8bpp.ico ico-size-3x3-8bpp.png
+== ico-size-4x4-8bpp.ico ico-size-4x4-8bpp.png
+== ico-size-5x5-8bpp.ico ico-size-5x5-8bpp.png
+== ico-size-6x6-8bpp.ico ico-size-6x6-8bpp.png
+== ico-size-7x7-8bpp.ico ico-size-7x7-8bpp.png
+== ico-size-8x8-8bpp.ico ico-size-8x8-8bpp.png
+== ico-size-9x9-8bpp.ico ico-size-9x9-8bpp.png
+== ico-size-15x15-8bpp.ico ico-size-15x15-8bpp.png
+== ico-size-16x16-8bpp.ico ico-size-16x16-8bpp.png
+== ico-size-17x17-8bpp.ico ico-size-17x17-8bpp.png
+== ico-size-31x31-8bpp.ico ico-size-31x31-8bpp.png
+== ico-size-32x32-8bpp.ico ico-size-32x32-8bpp.png
+== ico-size-33x33-8bpp.ico ico-size-33x33-8bpp.png
+== ico-size-256x256-8bpp.ico ico-size-256x256-8bpp.png
+== ico-partial-transparent-8bpp.ico ico-partial-transparent-8bpp.png
+== ico-transparent-8bpp.ico ico-transparent-8bpp.png
+== ico-not-square-transparent-8bpp.ico ico-not-square-transparent-8bpp.png
+
diff --git a/image/test/reftest/ico/ico-bmp-corrupted/16x16.png b/image/test/reftest/ico/ico-bmp-corrupted/16x16.png
new file mode 100644
index 0000000000..c04869e728
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-corrupted/16x16.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-corrupted/invalid-bpp.ico b/image/test/reftest/ico/ico-bmp-corrupted/invalid-bpp.ico
new file mode 100644
index 0000000000..1189e4c040
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-corrupted/invalid-bpp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-corrupted/invalid-compression-RLE4.ico b/image/test/reftest/ico/ico-bmp-corrupted/invalid-compression-RLE4.ico
new file mode 100644
index 0000000000..8fd0a5d658
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-corrupted/invalid-compression-RLE4.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-corrupted/invalid-compression-RLE8.ico b/image/test/reftest/ico/ico-bmp-corrupted/invalid-compression-RLE8.ico
new file mode 100644
index 0000000000..1f185ca620
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-corrupted/invalid-compression-RLE8.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-corrupted/invalid-compression.ico b/image/test/reftest/ico/ico-bmp-corrupted/invalid-compression.ico
new file mode 100644
index 0000000000..a49a783c5f
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-corrupted/invalid-compression.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-bmp-corrupted/reftest.list b/image/test/reftest/ico/ico-bmp-corrupted/reftest.list
new file mode 100644
index 0000000000..2467b1323e
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-corrupted/reftest.list
@@ -0,0 +1,10 @@
+# ICOs containing corrupted BMP tests
+
+# Invalid value for bits per pixel (BPP) - detected when decoding the header.
+== wrapper.html?invalid-bpp.ico about:blank
+# Invalid BPP values for RLE4 - detected when decoding the image data.
+== wrapper.html?invalid-compression-RLE4.ico about:blank
+# Invalid BPP values for RLE8 - detected when decoding the image data.
+== wrapper.html?invalid-compression-RLE8.ico about:blank
+# Invalid compression value - detected when decoding the image data.
+== wrapper.html?invalid-compression.ico about:blank
diff --git a/image/test/reftest/ico/ico-bmp-corrupted/wrapper.html b/image/test/reftest/ico/ico-bmp-corrupted/wrapper.html
new file mode 100644
index 0000000000..943bc75bf2
--- /dev/null
+++ b/image/test/reftest/ico/ico-bmp-corrupted/wrapper.html
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Image reftest wrapper</title>
+<style type="text/css">
+ #image1 { background-color: rgb(10, 100, 250); }
+</style>
+<script>
+ var gImg;
+
+ function runAfterAsyncEvents(aCallback) {
+ function handlePostMessage(aEvent) {
+ if (aEvent.data == 'next') {
+ window.removeEventListener('message', handlePostMessage);
+ aCallback();
+ }
+ }
+
+ window.addEventListener('message', handlePostMessage);
+
+ // We'll receive the 'message' event after everything else that's currently in
+ // the event queue (which is a stronger guarantee than setTimeout, because
+ // setTimeout events may be coalesced). This lets us ensure that we run
+ // aCallback *after* any asynchronous events are delivered.
+ window.postMessage('next', '*');
+ }
+
+ // The image is loaded async after the page loads
+ // wait for it to finish loading
+ function onImageLoad() {
+ // Use a canvas to force the image to get sync decoded.
+ var canvas = document.createElement('canvas');
+ var ctx = canvas.getContext('2d');
+
+ try {
+ ctx.drawImage(gImg, 0, 0);
+ } catch (e) {
+ }
+
+ // Continue after pumping the event loop.
+ runAfterAsyncEvents(step2);
+ }
+
+ function step2() {
+ // Only now, once the image has already been sync decoded, do we load it in
+ // the <img> element we're going to snapshot. That's because for some of the
+ // tests that use wrapper.html, an error is only detected when decoding the
+ // actual image data - i.e., the error isn't detected in the header. The
+ // precise time when we detect the error, unfortunately, affects how we draw
+ // the image. This will be fixed in bug 1182531, and then we can simplify this
+ // code.
+
+ var finalImg = document.getElementById('image1');
+ finalImg.onload = finalImg.onerror = step3;
+ finalImg.src = gImg.src;
+ }
+
+ function step3() {
+ // We're ready to take the snapshot, but pump the event loop first just to
+ // be sure that everything has settled down.
+ runAfterAsyncEvents(takeSnapshot);
+ }
+
+ function takeSnapshot() {
+ document.documentElement.removeAttribute("class");
+ }
+</script>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img id="image1" alt=" ">
+<script>
+ // Use as "wrapper.html?image.png
+ gImg = document.createElement('img');
+ gImg.onload = gImg.onerror = onImageLoad;
+ gImg.src = document.location.search.substr(1);
+</script>
+</body>
+</html>
+
diff --git a/image/test/reftest/ico/ico-mixed/mixed-bmp-png.ico b/image/test/reftest/ico/ico-mixed/mixed-bmp-png.ico
new file mode 100644
index 0000000000..32e2c4995c
--- /dev/null
+++ b/image/test/reftest/ico/ico-mixed/mixed-bmp-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-mixed/mixed-bmp-png.png b/image/test/reftest/ico/ico-mixed/mixed-bmp-png.png
new file mode 100644
index 0000000000..b6aee74092
--- /dev/null
+++ b/image/test/reftest/ico/ico-mixed/mixed-bmp-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-mixed/mixed-bmp-png32.png b/image/test/reftest/ico/ico-mixed/mixed-bmp-png32.png
new file mode 100644
index 0000000000..a058991272
--- /dev/null
+++ b/image/test/reftest/ico/ico-mixed/mixed-bmp-png32.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-mixed/mixed-bmp-png48.png b/image/test/reftest/ico/ico-mixed/mixed-bmp-png48.png
new file mode 100644
index 0000000000..61bea5c804
--- /dev/null
+++ b/image/test/reftest/ico/ico-mixed/mixed-bmp-png48.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-mixed/reftest.list b/image/test/reftest/ico/ico-mixed/reftest.list
new file mode 100644
index 0000000000..36134e40ab
--- /dev/null
+++ b/image/test/reftest/ico/ico-mixed/reftest.list
@@ -0,0 +1,3 @@
+# ICO BMP and PNG mixed tests
+
+== mixed-bmp-png.ico mixed-bmp-png48.png
diff --git a/image/test/reftest/ico/ico-png/corrupted_x00n0g01.ico b/image/test/reftest/ico/ico-png/corrupted_x00n0g01.ico
new file mode 100644
index 0000000000..18b97b0b7e
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/corrupted_x00n0g01.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/corrupted_xxcrn0g04.ico b/image/test/reftest/ico/ico-png/corrupted_xxcrn0g04.ico
new file mode 100644
index 0000000000..3fa5285c5b
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/corrupted_xxcrn0g04.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-15x15-png.ico b/image/test/reftest/ico/ico-png/ico-size-15x15-png.ico
new file mode 100644
index 0000000000..e67644a890
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-15x15-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-15x15-png.png b/image/test/reftest/ico/ico-png/ico-size-15x15-png.png
new file mode 100644
index 0000000000..e1287430d0
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-15x15-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-16x16-png.ico b/image/test/reftest/ico/ico-png/ico-size-16x16-png.ico
new file mode 100644
index 0000000000..442ab4dc80
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-16x16-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-16x16-png.png b/image/test/reftest/ico/ico-png/ico-size-16x16-png.png
new file mode 100644
index 0000000000..c04869e728
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-16x16-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-17x17-png.ico b/image/test/reftest/ico/ico-png/ico-size-17x17-png.ico
new file mode 100644
index 0000000000..f135385d7e
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-17x17-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-17x17-png.png b/image/test/reftest/ico/ico-png/ico-size-17x17-png.png
new file mode 100644
index 0000000000..00fb8e4f37
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-17x17-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-1x1-png.ico b/image/test/reftest/ico/ico-png/ico-size-1x1-png.ico
new file mode 100644
index 0000000000..8eb80c7db2
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-1x1-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-1x1-png.png b/image/test/reftest/ico/ico-png/ico-size-1x1-png.png
new file mode 100644
index 0000000000..c05f5fef89
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-1x1-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-256x256-png.ico b/image/test/reftest/ico/ico-png/ico-size-256x256-png.ico
new file mode 100644
index 0000000000..ecb88edf3c
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-256x256-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-256x256-png.png b/image/test/reftest/ico/ico-png/ico-size-256x256-png.png
new file mode 100644
index 0000000000..2d2f52d6c1
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-256x256-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-2x2-png.ico b/image/test/reftest/ico/ico-png/ico-size-2x2-png.ico
new file mode 100644
index 0000000000..5799953c98
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-2x2-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-2x2-png.png b/image/test/reftest/ico/ico-png/ico-size-2x2-png.png
new file mode 100644
index 0000000000..e512d3f9b4
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-2x2-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-31x31-png.ico b/image/test/reftest/ico/ico-png/ico-size-31x31-png.ico
new file mode 100644
index 0000000000..2e9fbd8f9c
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-31x31-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-31x31-png.png b/image/test/reftest/ico/ico-png/ico-size-31x31-png.png
new file mode 100644
index 0000000000..e4a8642514
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-31x31-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-32x32-png.ico b/image/test/reftest/ico/ico-png/ico-size-32x32-png.ico
new file mode 100644
index 0000000000..af97a86630
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-32x32-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-32x32-png.png b/image/test/reftest/ico/ico-png/ico-size-32x32-png.png
new file mode 100644
index 0000000000..3a6fbe8ee9
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-32x32-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-33x33-png.ico b/image/test/reftest/ico/ico-png/ico-size-33x33-png.ico
new file mode 100644
index 0000000000..2509c8c1f2
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-33x33-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-33x33-png.png b/image/test/reftest/ico/ico-png/ico-size-33x33-png.png
new file mode 100644
index 0000000000..72ef7eb636
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-33x33-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-3x3-png.ico b/image/test/reftest/ico/ico-png/ico-size-3x3-png.ico
new file mode 100644
index 0000000000..d2cd649c84
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-3x3-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-3x3-png.png b/image/test/reftest/ico/ico-png/ico-size-3x3-png.png
new file mode 100644
index 0000000000..cb42ec4f87
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-3x3-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-4x4-png.ico b/image/test/reftest/ico/ico-png/ico-size-4x4-png.ico
new file mode 100644
index 0000000000..60180aad5e
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-4x4-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-4x4-png.png b/image/test/reftest/ico/ico-png/ico-size-4x4-png.png
new file mode 100644
index 0000000000..e6afafd89a
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-4x4-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-5x5-png.ico b/image/test/reftest/ico/ico-png/ico-size-5x5-png.ico
new file mode 100644
index 0000000000..089c0c8858
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-5x5-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-5x5-png.png b/image/test/reftest/ico/ico-png/ico-size-5x5-png.png
new file mode 100644
index 0000000000..a844aff76d
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-5x5-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-6x6-png.ico b/image/test/reftest/ico/ico-png/ico-size-6x6-png.ico
new file mode 100644
index 0000000000..2ee75d25ab
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-6x6-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-6x6-png.png b/image/test/reftest/ico/ico-png/ico-size-6x6-png.png
new file mode 100644
index 0000000000..415c2d9c6a
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-6x6-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-7x7-png.ico b/image/test/reftest/ico/ico-png/ico-size-7x7-png.ico
new file mode 100644
index 0000000000..ade9a3ecde
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-7x7-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-7x7-png.png b/image/test/reftest/ico/ico-png/ico-size-7x7-png.png
new file mode 100644
index 0000000000..ab2f892747
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-7x7-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-8x8-png.ico b/image/test/reftest/ico/ico-png/ico-size-8x8-png.ico
new file mode 100644
index 0000000000..a0a150bad6
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-8x8-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-8x8-png.png b/image/test/reftest/ico/ico-png/ico-size-8x8-png.png
new file mode 100644
index 0000000000..fe2ff40a1d
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-8x8-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-9x9-png.ico b/image/test/reftest/ico/ico-png/ico-size-9x9-png.ico
new file mode 100644
index 0000000000..a53357b449
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-9x9-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/ico-size-9x9-png.png b/image/test/reftest/ico/ico-png/ico-size-9x9-png.png
new file mode 100644
index 0000000000..18ab4b25de
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/ico-size-9x9-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/reftest.list b/image/test/reftest/ico/ico-png/reftest.list
new file mode 100644
index 0000000000..002d0e4f32
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/reftest.list
@@ -0,0 +1,29 @@
+# ICO PNG tests
+
+# Images of various sizes
+== ico-size-1x1-png.ico ico-size-1x1-png.png
+== ico-size-2x2-png.ico ico-size-2x2-png.png
+== ico-size-3x3-png.ico ico-size-3x3-png.png
+== ico-size-4x4-png.ico ico-size-4x4-png.png
+== ico-size-5x5-png.ico ico-size-5x5-png.png
+== ico-size-6x6-png.ico ico-size-6x6-png.png
+== ico-size-7x7-png.ico ico-size-7x7-png.png
+== ico-size-8x8-png.ico ico-size-8x8-png.png
+== ico-size-9x9-png.ico ico-size-9x9-png.png
+== ico-size-15x15-png.ico ico-size-15x15-png.png
+== ico-size-16x16-png.ico ico-size-16x16-png.png
+== ico-size-17x17-png.ico ico-size-17x17-png.png
+== ico-size-31x31-png.ico ico-size-31x31-png.png
+== ico-size-32x32-png.ico ico-size-32x32-png.png
+== ico-size-33x33-png.ico ico-size-33x33-png.png
+== ico-size-256x256-png.ico ico-size-256x256-png.png
+
+# Corrupted files so no image should be loaded
+# x00n0g01 - empty 0x0 grayscale file
+== wrapper.html?x00n0g01.ico about:blank
+# xcrn0g04 - added cr bytes
+== wrapper.html?xcrn0g04.ico about:blank
+
+# Test ICO PNG transparency
+== transparent-png.ico transparent-png.png
+
diff --git a/image/test/reftest/ico/ico-png/tmp.ico b/image/test/reftest/ico/ico-png/tmp.ico
new file mode 100644
index 0000000000..5723a2e776
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/tmp.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/transparent-png.ico b/image/test/reftest/ico/ico-png/transparent-png.ico
new file mode 100644
index 0000000000..cc8a4a31db
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/transparent-png.ico
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/transparent-png.png b/image/test/reftest/ico/ico-png/transparent-png.png
new file mode 100644
index 0000000000..29e3a24359
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/transparent-png.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/wrapper.html b/image/test/reftest/ico/ico-png/wrapper.html
new file mode 100644
index 0000000000..45b5167754
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/wrapper.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Image reftest wrapper</title>
+<style type="text/css">
+ #image1 { background-color: rgb(10, 100, 250); }
+</style>
+<script>
+ // The image is loaded async after the page loads
+ // wait for it to finish loading
+ function onImageLoad() {
+ document.documentElement.removeAttribute("class");
+ };
+</script>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img id="image1" alt=" ">
+<script>
+ // Use as "wrapper.html?image.png
+ var imgURL = document.location.search.substr(1);
+ document.images[0].onload = onImageLoad;
+ document.images[0].onerror = onImageLoad;
+ document.images[0].src = imgURL;
+</script>
+</body>
+</html>
+
diff --git a/image/test/reftest/ico/ico-png/x00n0g01.png b/image/test/reftest/ico/ico-png/x00n0g01.png
new file mode 100644
index 0000000000..db3a5fda7e
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/x00n0g01.png
Binary files differ
diff --git a/image/test/reftest/ico/ico-png/xcrn0g04.png b/image/test/reftest/ico/ico-png/xcrn0g04.png
new file mode 100644
index 0000000000..5bce9f3ada
--- /dev/null
+++ b/image/test/reftest/ico/ico-png/xcrn0g04.png
Binary files differ
diff --git a/image/test/reftest/ico/reftest.list b/image/test/reftest/ico/reftest.list
new file mode 100644
index 0000000000..22ed9b4fe7
--- /dev/null
+++ b/image/test/reftest/ico/reftest.list
@@ -0,0 +1,11 @@
+# ICO tests
+
+include ico-bmp-1bpp/reftest.list
+include ico-bmp-4bpp/reftest.list
+include ico-bmp-8bpp/reftest.list
+include ico-bmp-24bpp/reftest.list
+include ico-bmp-32bpp/reftest.list
+include ico-bmp-corrupted/reftest.list
+include ico-png/reftest.list
+include ico-mixed/reftest.list
+include cur/reftest.list
diff --git a/image/test/reftest/img2html.html b/image/test/reftest/img2html.html
new file mode 100644
index 0000000000..57f45bbdd3
--- /dev/null
+++ b/image/test/reftest/img2html.html
@@ -0,0 +1,122 @@
+<html>
+<head>
+<title>Image-to-html converter</title>
+<style>
+#img, #canvas, #span {
+ display: none;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAL0lEQVQ4jWP09vZ+xoAHuLi44JNmYMIrSwQYNWAwGMBCKJ737NlDWxeMGjAYDAAAak4FtfgpsBoAAAAASUVORK5CYII=);
+}
+</style>
+</head>
+<body>
+<h2>Image-to-html converter</h2>
+<p>Enter the relative path to an image file, and this will convert it
+to a pure HTML representation (no images).</p>
+
+
+<form onsubmit="start_convert(); return false;">
+ Path to image: <input type="text" id="filepath" size="60"><br>
+ <input id="fill" type="checkbox">
+ Fill canvas with <input id="fillRGB" value="rgb(10,100,250)"> (instead of transparency).<br>
+ <button type='submit'>Convert!</button>
+ <br><br>
+ <img id="img" onload="run_convert();"><canvas id="canvas"></canvas><span id="span"></span><br>
+ (img / canvas/ imghtml)
+ <br><br>
+ Result:<br>
+ <textarea id="textarea" rows="10" cols="80"></textarea>
+</form>
+
+
+<script>
+var img = document.getElementById("img");
+var canvas = document.getElementById("canvas");
+var span = document.getElementById("span");
+var textarea = document.getElementById("textarea");
+var fill = document.getElementById("fill");
+var fillRGB = document.getElementById("fillRGB");
+
+function start_convert() {
+ try {
+
+ // Unhide stuff. They're initially hidden because the image shows a
+ // broken-image icon on first page load, and the canvas defaults to a
+ // large empty area.
+ img.style.display = "inline";
+ canvas.style.display = "inline";
+ span.style.display = "inline-block";
+
+ // Clear out any previous values.
+ textarea.value = "(loading image)"
+ span.innerHTML = "";
+
+ // Get the image filename
+ var input = document.getElementById("filepath");
+ img.src = input.value;
+
+ // We're done, let the onload handler do the real work.
+ } catch (e) {
+ alert("Crap, start_convert failed: " + e);
+ }
+}
+
+function run_convert() {
+ try {
+ textarea.value = "(rendering canvas)";
+
+ canvas.width = img.width;
+ canvas.height = img.height;
+ var ctx = canvas.getContext("2d");
+ ctx.clearRect(0, 0, img.width, img.height);
+ if (fill.checked) {
+ ctx.fillStyle = fillRGB.value;
+ ctx.fillRect (0, 0, img.width, img.height);
+ }
+ ctx.drawImage(img, 0, 0);
+
+ // [r, g, b, a, r, g, b, a, ...]
+ var pixels = ctx.getImageData(0, 0, img.width, img.height).data;
+
+ var imghtml = "<table cellpadding='0' cellspacing='0' width='" +
+ img.width + "' height='" + img.height + "'>\n";
+
+ for (var y = 0; y < img.height; y++) {
+ imghtml += "<tr height='1'>\n";
+
+ textarea.value = "(converting row " + y + ")";
+
+ for (var x = 0; x < img.width; x++) {
+ var p = img.width * y * 4 + x * 4;
+
+ var r = pixels[p + 0];
+ var g = pixels[p + 1];
+ var b = pixels[p + 2];
+ var a = pixels[p + 3];
+
+ var alpha = (a / 255).toString();
+ alpha = alpha.substring(0, 6); // "0.12345678 --> 0.1234"
+ imghtml += " <td width='1' style='background-color: " +
+ "rgba(" +
+ r + "," +
+ g + "," +
+ b + "," +
+ alpha +
+ ")'></td>\n";
+ }
+
+ imghtml += "</tr>\n";
+ }
+
+ imghtml += "</table>\n";
+
+ span.innerHTML = imghtml;
+ textarea.value = "<html><body>\n" + imghtml + "</body></html>";
+
+ } catch (e) {
+ alert("Crap, run_convert failed: " + e);
+ }
+}
+</script>
+
+</body>
+</html>
diff --git a/image/test/reftest/jpeg/blue.html b/image/test/reftest/jpeg/blue.html
new file mode 100644
index 0000000000..3f4bb44f7e
--- /dev/null
+++ b/image/test/reftest/jpeg/blue.html
@@ -0,0 +1 @@
+<img src="blue.jpg">
diff --git a/image/test/reftest/jpeg/blue.jpg b/image/test/reftest/jpeg/blue.jpg
new file mode 100644
index 0000000000..b5fef5d26c
--- /dev/null
+++ b/image/test/reftest/jpeg/blue.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-cmyk-1.jpg b/image/test/reftest/jpeg/jpg-cmyk-1.jpg
new file mode 100644
index 0000000000..ddb2c106f2
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-cmyk-1.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-cmyk-1.png b/image/test/reftest/jpeg/jpg-cmyk-1.png
new file mode 100644
index 0000000000..06915d5bce
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-cmyk-1.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-cmyk-2.jpg b/image/test/reftest/jpeg/jpg-cmyk-2.jpg
new file mode 100644
index 0000000000..b955bde549
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-cmyk-2.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-cmyk-2.png b/image/test/reftest/jpeg/jpg-cmyk-2.png
new file mode 100644
index 0000000000..9691e42b65
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-cmyk-2.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-gray.jpg b/image/test/reftest/jpeg/jpg-gray.jpg
new file mode 100644
index 0000000000..af0413e3c1
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-gray.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-gray.png b/image/test/reftest/jpeg/jpg-gray.png
new file mode 100644
index 0000000000..c5aedc34dc
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-gray.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-progressive-1000-ref.html b/image/test/reftest/jpeg/jpg-progressive-1000-ref.html
new file mode 100644
index 0000000000..0ff2497102
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-progressive-1000-ref.html
@@ -0,0 +1 @@
+<img src="nosuchurl">
diff --git a/image/test/reftest/jpeg/jpg-progressive-1000.html b/image/test/reftest/jpeg/jpg-progressive-1000.html
new file mode 100644
index 0000000000..b9eaf9c53a
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-progressive-1000.html
@@ -0,0 +1 @@
+<img src="jpg-progressive-1000.jpg">
diff --git a/image/test/reftest/jpeg/jpg-progressive-1000.jpg b/image/test/reftest/jpeg/jpg-progressive-1000.jpg
new file mode 100644
index 0000000000..65a4325b53
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-progressive-1000.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-progressive.jpg b/image/test/reftest/jpeg/jpg-progressive.jpg
new file mode 100644
index 0000000000..db3cf59c26
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-progressive.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-progressive.png b/image/test/reftest/jpeg/jpg-progressive.png
new file mode 100644
index 0000000000..3a6fbe8ee9
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-progressive.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-15x15.jpg b/image/test/reftest/jpeg/jpg-size-15x15.jpg
new file mode 100644
index 0000000000..efe120a27f
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-15x15.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-15x15.png b/image/test/reftest/jpeg/jpg-size-15x15.png
new file mode 100644
index 0000000000..e1287430d0
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-15x15.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-16x16.jpg b/image/test/reftest/jpeg/jpg-size-16x16.jpg
new file mode 100644
index 0000000000..148ec733f9
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-16x16.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-16x16.png b/image/test/reftest/jpeg/jpg-size-16x16.png
new file mode 100644
index 0000000000..c04869e728
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-16x16.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-17x17.jpg b/image/test/reftest/jpeg/jpg-size-17x17.jpg
new file mode 100644
index 0000000000..b06bdb0d69
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-17x17.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-17x17.png b/image/test/reftest/jpeg/jpg-size-17x17.png
new file mode 100644
index 0000000000..00fb8e4f37
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-17x17.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-1x1.jpg b/image/test/reftest/jpeg/jpg-size-1x1.jpg
new file mode 100644
index 0000000000..73b68dfc06
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-1x1.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-1x1.png b/image/test/reftest/jpeg/jpg-size-1x1.png
new file mode 100644
index 0000000000..c05f5fef89
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-1x1.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-2x2.jpg b/image/test/reftest/jpeg/jpg-size-2x2.jpg
new file mode 100644
index 0000000000..bc50260ea6
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-2x2.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-2x2.png b/image/test/reftest/jpeg/jpg-size-2x2.png
new file mode 100644
index 0000000000..e512d3f9b4
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-2x2.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-31x31.jpg b/image/test/reftest/jpeg/jpg-size-31x31.jpg
new file mode 100644
index 0000000000..8fa0cc2367
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-31x31.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-31x31.png b/image/test/reftest/jpeg/jpg-size-31x31.png
new file mode 100644
index 0000000000..e4a8642514
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-31x31.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-32x32.jpg b/image/test/reftest/jpeg/jpg-size-32x32.jpg
new file mode 100644
index 0000000000..b11d62df6d
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-32x32.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-32x32.png b/image/test/reftest/jpeg/jpg-size-32x32.png
new file mode 100644
index 0000000000..3a6fbe8ee9
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-32x32.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-33x33.jpg b/image/test/reftest/jpeg/jpg-size-33x33.jpg
new file mode 100644
index 0000000000..5ac1169b4b
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-33x33.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-33x33.png b/image/test/reftest/jpeg/jpg-size-33x33.png
new file mode 100644
index 0000000000..72ef7eb636
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-33x33.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-3x3.jpg b/image/test/reftest/jpeg/jpg-size-3x3.jpg
new file mode 100644
index 0000000000..cf370d8ece
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-3x3.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-3x3.png b/image/test/reftest/jpeg/jpg-size-3x3.png
new file mode 100644
index 0000000000..cb42ec4f87
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-3x3.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-4x4.jpg b/image/test/reftest/jpeg/jpg-size-4x4.jpg
new file mode 100644
index 0000000000..5adf760a1b
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-4x4.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-4x4.png b/image/test/reftest/jpeg/jpg-size-4x4.png
new file mode 100644
index 0000000000..e6afafd89a
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-4x4.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-5x5.jpg b/image/test/reftest/jpeg/jpg-size-5x5.jpg
new file mode 100644
index 0000000000..4d5fd0501c
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-5x5.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-5x5.png b/image/test/reftest/jpeg/jpg-size-5x5.png
new file mode 100644
index 0000000000..a844aff76d
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-5x5.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-6x6.jpg b/image/test/reftest/jpeg/jpg-size-6x6.jpg
new file mode 100644
index 0000000000..415c2d9c6a
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-6x6.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-6x6.png b/image/test/reftest/jpeg/jpg-size-6x6.png
new file mode 100644
index 0000000000..415c2d9c6a
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-6x6.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-7x7.jpg b/image/test/reftest/jpeg/jpg-size-7x7.jpg
new file mode 100644
index 0000000000..5495f7e43e
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-7x7.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-7x7.png b/image/test/reftest/jpeg/jpg-size-7x7.png
new file mode 100644
index 0000000000..ab2f892747
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-7x7.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-8x8.jpg b/image/test/reftest/jpeg/jpg-size-8x8.jpg
new file mode 100644
index 0000000000..84a5c8f426
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-8x8.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-8x8.png b/image/test/reftest/jpeg/jpg-size-8x8.png
new file mode 100644
index 0000000000..fe2ff40a1d
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-8x8.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-9x9.jpg b/image/test/reftest/jpeg/jpg-size-9x9.jpg
new file mode 100644
index 0000000000..d0a15e599f
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-9x9.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-size-9x9.png b/image/test/reftest/jpeg/jpg-size-9x9.png
new file mode 100644
index 0000000000..18ab4b25de
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-size-9x9.png
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-srgb-icc.jpg b/image/test/reftest/jpeg/jpg-srgb-icc.jpg
new file mode 100644
index 0000000000..3ebefac732
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-srgb-icc.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/jpg-srgb-icc.png b/image/test/reftest/jpeg/jpg-srgb-icc.png
new file mode 100644
index 0000000000..1d8efc687a
--- /dev/null
+++ b/image/test/reftest/jpeg/jpg-srgb-icc.png
Binary files differ
diff --git a/image/test/reftest/jpeg/non-interleaved_progressive-1-halfred-ref.png b/image/test/reftest/jpeg/non-interleaved_progressive-1-halfred-ref.png
new file mode 100644
index 0000000000..7d0c9e5580
--- /dev/null
+++ b/image/test/reftest/jpeg/non-interleaved_progressive-1-halfred-ref.png
Binary files differ
diff --git a/image/test/reftest/jpeg/non-interleaved_progressive-1.jpg b/image/test/reftest/jpeg/non-interleaved_progressive-1.jpg
new file mode 100644
index 0000000000..5128473dfd
--- /dev/null
+++ b/image/test/reftest/jpeg/non-interleaved_progressive-1.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/non-interleaved_progressive-2-white-ref.png b/image/test/reftest/jpeg/non-interleaved_progressive-2-white-ref.png
new file mode 100644
index 0000000000..597329a663
--- /dev/null
+++ b/image/test/reftest/jpeg/non-interleaved_progressive-2-white-ref.png
Binary files differ
diff --git a/image/test/reftest/jpeg/non-interleaved_progressive-2.jpg b/image/test/reftest/jpeg/non-interleaved_progressive-2.jpg
new file mode 100644
index 0000000000..d4c80e9124
--- /dev/null
+++ b/image/test/reftest/jpeg/non-interleaved_progressive-2.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/red-bad-marker.jpg b/image/test/reftest/jpeg/red-bad-marker.jpg
new file mode 100644
index 0000000000..4abda17e59
--- /dev/null
+++ b/image/test/reftest/jpeg/red-bad-marker.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/red.jpg b/image/test/reftest/jpeg/red.jpg
new file mode 100644
index 0000000000..8fca4b938f
--- /dev/null
+++ b/image/test/reftest/jpeg/red.jpg
Binary files differ
diff --git a/image/test/reftest/jpeg/reftest.list b/image/test/reftest/jpeg/reftest.list
new file mode 100644
index 0000000000..d8723b8071
--- /dev/null
+++ b/image/test/reftest/jpeg/reftest.list
@@ -0,0 +1,73 @@
+# JPEG tests
+
+# Images of various sizes.
+== jpg-size-1x1.jpg jpg-size-1x1.png
+== jpg-size-2x2.jpg jpg-size-2x2.png
+== jpg-size-3x3.jpg jpg-size-3x3.png
+== jpg-size-4x4.jpg jpg-size-4x4.png
+== jpg-size-5x5.jpg jpg-size-5x5.png
+== jpg-size-6x6.jpg jpg-size-6x6.png
+== jpg-size-7x7.jpg jpg-size-7x7.png
+== jpg-size-8x8.jpg jpg-size-8x8.png
+== jpg-size-9x9.jpg jpg-size-9x9.png
+== jpg-size-15x15.jpg jpg-size-15x15.png
+== jpg-size-16x16.jpg jpg-size-16x16.png
+== jpg-size-17x17.jpg jpg-size-17x17.png
+== jpg-size-31x31.jpg jpg-size-31x31.png
+== jpg-size-32x32.jpg jpg-size-32x32.png
+== jpg-size-33x33.jpg jpg-size-33x33.png
+# Progressive encoding
+== jpg-progressive.jpg jpg-progressive.png
+# Grayscale colorspace
+== jpg-gray.jpg jpg-gray.png
+# CMYK colorspace
+== jpg-cmyk-1.jpg jpg-cmyk-1.png
+== jpg-cmyk-2.jpg jpg-cmyk-2.png
+# This intermittently fails on Android due to async image decoding (bug #685516)
+# Sometimes the image decodes in time and the test passes, other times the image
+# appears blank and the test fails. This only seems to be triggered since the
+# switch to 24-bit colour (bug #803299).
+random-if(Android) == jpg-srgb-icc.jpg jpg-srgb-icc.png
+
+# webcam-simulacrum.mjpg is a hand-edited file containing red.jpg and blue.jpg,
+# concatenated together with the relevant headers for
+# multipart/x-mixed-replace. Specifically, with the headers in
+# webcam-simulacrum.mjpg^headers^, the web browser will get the following:
+#
+# HTTP 200 OK
+# Content-Type: multipart/x-mixed-replace;boundary=BOUNDARYOMG
+#
+# --BOUNDARYOMG\r\n
+# Content-Type: image/jpeg\r\n
+# \r\n
+# <contents of red.jpg> (no newline)
+# --BOUNDARYOMG\r\n
+# Content-Type: image/jpeg\r\n
+# \r\n
+# <contents of blue.jpg> (no newline)
+# --BOUNDARYOMG--\r\n
+#
+# (The boundary is arbitrary, and just has to be defined as something that
+# won't be in the text of the contents themselves. --$(boundary)\r\n means
+# "Here is the beginning of a boundary," and --$(boundary)-- means "All done
+# sending you parts.")
+HTTP == webcam-simulacrum.mjpg blue.jpg
+# Same as the above but as img elements in html files to get better test
+# coverage of multipart images.
+# Images loaded at the top level are actually loaded into an ImageDocument
+# which is a slim html document wrapper around the image.
+# Multipart images send multiple OnStartRequest's, each OnStartRequest causes
+# us to create a new ImageDocument to show the next part.
+# This differs from displaying a multipart image in an img element in a regular
+# document where we use the same document and same elements and same layout
+# frames for each part. So we have this testcase to test those different
+# codepaths.
+HTTP == webcam-simulacrum.html blue.html
+
+== non-interleaved_progressive-1.jpg non-interleaved_progressive-1-halfred-ref.png
+== non-interleaved_progressive-2.jpg non-interleaved_progressive-2-white-ref.png
+
+== red-bad-marker.jpg red.jpg
+
+# check that we reject jpegs with > 1000 scans
+== jpg-progressive-1000.html jpg-progressive-1000-ref.html
diff --git a/image/test/reftest/jpeg/webcam-simulacrum.html b/image/test/reftest/jpeg/webcam-simulacrum.html
new file mode 100644
index 0000000000..2fc6395c7a
--- /dev/null
+++ b/image/test/reftest/jpeg/webcam-simulacrum.html
@@ -0,0 +1 @@
+<img src="webcam-simulacrum.mjpg">
diff --git a/image/test/reftest/jpeg/webcam-simulacrum.mjpg b/image/test/reftest/jpeg/webcam-simulacrum.mjpg
new file mode 100644
index 0000000000..a593273c0e
--- /dev/null
+++ b/image/test/reftest/jpeg/webcam-simulacrum.mjpg
Binary files differ
diff --git a/image/test/reftest/jpeg/webcam-simulacrum.mjpg^headers^ b/image/test/reftest/jpeg/webcam-simulacrum.mjpg^headers^
new file mode 100644
index 0000000000..f5e846508e
--- /dev/null
+++ b/image/test/reftest/jpeg/webcam-simulacrum.mjpg^headers^
@@ -0,0 +1,3 @@
+HTTP 200 OK
+Content-Type: multipart/x-mixed-replace;boundary=BOUNDARYOMG
+Cache-Control: no-cache
diff --git a/image/test/reftest/jxl/jxl-size-33x33.jxl b/image/test/reftest/jxl/jxl-size-33x33.jxl
new file mode 100644
index 0000000000..da7c1c76f1
--- /dev/null
+++ b/image/test/reftest/jxl/jxl-size-33x33.jxl
Binary files differ
diff --git a/image/test/reftest/jxl/jxl-size-33x33.png b/image/test/reftest/jxl/jxl-size-33x33.png
new file mode 100644
index 0000000000..72ef7eb636
--- /dev/null
+++ b/image/test/reftest/jxl/jxl-size-33x33.png
Binary files differ
diff --git a/image/test/reftest/jxl/reftest.list b/image/test/reftest/jxl/reftest.list
new file mode 100644
index 0000000000..04819b5543
--- /dev/null
+++ b/image/test/reftest/jxl/reftest.list
@@ -0,0 +1,3 @@
+# JXL tests
+
+pref(image.jxl.enabled,true) == jxl-size-33x33.jxl jxl-size-33x33.png
diff --git a/image/test/reftest/pngsuite-ancillary/ccwn2c08.html b/image/test/reftest/pngsuite-ancillary/ccwn2c08.html
new file mode 100644
index 0000000000..dc4996e2b0
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ccwn2c08.html
@@ -0,0 +1,1242 @@
+<html>
+<head>
+<link rel="stylesheet" href="../ImageDocument.css">
+<script src="qcms-asm-check.js" type="application/ecmascript"></script>
+<!-- generated with:
+import png
+import sys
+print """<html>
+<head>
+<script src="qcms-asm-check.js" type="application/ecmascript"></script>
+<!-""" + """- generated with:"""
+print open(__file__).read()
+print "-" + """->
+</head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>"""
+r1 = png.Reader(file=open(sys.argv[1]))
+r2 = png.Reader(file=open(sys.argv[2]))
+(data1, data2) = (r1.asDirect(), r2.asDirect())
+(pixels1, pixels2) = (list(data1[2])[8:32+8], list(data2[2])[8:32+8])
+planes = data1[3]['planes']
+for (line1, line2) in zip(pixels1, pixels2):
+ r1, g1, b1 = (line1[0::planes][8:32+8], line1[1::planes][8:32+8], line1[2::planes][8:32+8])
+ r2, g2, b2 = (line2[0::planes][8:32+8], line2[1::planes][8:32+8], line2[2::planes][8:32+8])
+ print "<tr height='1'>"
+ for (pixel1, pixel2) in zip(zip(r1,g1,b1), zip(r2,g2,b2)):
+ if pixel1[0] == pixel2[0] and pixel1[1] == pixel2[1] and pixel1[2] == pixel2[2]:
+ print " <td width='1' style='background-color: rgba(%d,%d,%d,1)'></td>" % (pixel1[0], pixel1[1], pixel1[2])
+ else:
+ print """<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(%d,%d,%d,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(%d,%d,%d,1)'></td>");
+}
+</script>""" % (pixel1[0], pixel1[1], pixel1[2], pixel2[0], pixel2[1], pixel2[2])
+ print "</tr>"
+print """</table>
+</body></html>"""
+
+-->
+</head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(226,255,236,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(225,255,236,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(161,254,196,1)'></td>
+ <td width='1' style='background-color: rgba(120,255,170,1)'></td>
+ <td width='1' style='background-color: rgba(161,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,220,1)'></td>
+ <td width='1' style='background-color: rgba(46,255,165,1)'></td>
+ <td width='1' style='background-color: rgba(61,255,160,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,153,1)'></td>
+ <td width='1' style='background-color: rgba(64,255,138,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,113,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,132,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(49,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,173,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(85,255,168,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(84,255,168,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(91,255,162,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,148,1)'></td>
+ <td width='1' style='background-color: rgba(81,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(86,255,93,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(122,255,59,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(122,255,58,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(210,255,190,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,243,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,182,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,181,1)'></td>
+ <td width='1' style='background-color: rgba(95,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,176,1)'></td>
+ <td width='1' style='background-color: rgba(110,255,170,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(103,255,137,1)'></td>
+ <td width='1' style='background-color: rgba(108,255,108,1)'></td>
+ <td width='1' style='background-color: rgba(135,255,73,1)'></td>
+ <td width='1' style='background-color: rgba(153,255,46,1)'></td>
+ <td width='1' style='background-color: rgba(201,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(252,255,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(142,255,208,1)'></td>
+ <td width='1' style='background-color: rgba(73,255,188,1)'></td>
+ <td width='1' style='background-color: rgba(95,255,187,1)'></td>
+ <td width='1' style='background-color: rgba(110,255,187,1)'></td>
+ <td width='1' style='background-color: rgba(120,255,184,1)'></td>
+ <td width='1' style='background-color: rgba(127,255,179,1)'></td>
+ <td width='1' style='background-color: rgba(126,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(121,255,148,1)'></td>
+ <td width='1' style='background-color: rgba(127,255,120,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(150,255,92,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(150,255,91,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(165,255,73,1)'></td>
+ <td width='1' style='background-color: rgba(176,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,133,1)'></td>
+ <td width='1' style='background-color: rgba(252,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(55,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(88,255,194,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,194,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(134,255,191,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,187,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,178,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(142,255,133,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,108,1)'></td>
+ <td width='1' style='background-color: rgba(176,255,95,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(195,255,56,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,133,1)'></td>
+ <td width='1' style='background-color: rgba(253,255,249,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(127,255,210,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,199,1)'></td>
+ <td width='1' style='background-color: rgba(121,255,199,1)'></td>
+ <td width='1' style='background-color: rgba(135,255,199,1)'></td>
+ <td width='1' style='background-color: rgba(146,255,197,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,194,1)'></td>
+ <td width='1' style='background-color: rgba(154,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(150,255,169,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,145,1)'></td>
+ <td width='1' style='background-color: rgba(175,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(187,255,112,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(196,255,98,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(195,255,98,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(204,255,79,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,56,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,133,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,253,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(55,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(91,255,203,1)'></td>
+ <td width='1' style='background-color: rgba(113,255,203,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,205,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,205,1)'></td>
+ <td width='1' style='background-color: rgba(157,255,203,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,201,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,194,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,178,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,138,1)'></td>
+ <td width='1' style='background-color: rgba(196,255,127,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,114,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,56,1)'></td>
+ <td width='1' style='background-color: rgba(244,255,153,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,253,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(170,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(73,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,208,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,209,1)'></td>
+ <td width='1' style='background-color: rgba(141,255,210,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,210,1)'></td>
+ <td width='1' style='background-color: rgba(167,255,209,1)'></td>
+ <td width='1' style='background-color: rgba(174,255,208,1)'></td>
+ <td width='1' style='background-color: rgba(177,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(174,255,188,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(196,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,128,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,114,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,96,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,173,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(249,255,253,1)'></td>
+ <td width='1' style='background-color: rgba(79,255,213,1)'></td>
+ <td width='1' style='background-color: rgba(86,255,211,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(133,255,214,1)'></td>
+ <td width='1' style='background-color: rgba(149,255,214,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,215,1)'></td>
+ <td width='1' style='background-color: rgba(175,255,215,1)'></td>
+ <td width='1' style='background-color: rgba(184,255,214,1)'></td>
+ <td width='1' style='background-color: rgba(187,255,209,1)'></td>
+ <td width='1' style='background-color: rgba(185,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,176,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,154,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,141,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,128,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,113,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,96,1)'></td>
+ <td width='1' style='background-color: rgba(254,253,75,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,49,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(210,255,241,1)'></td>
+ <td width='1' style='background-color: rgba(64,255,214,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,215,1)'></td>
+ <td width='1' style='background-color: rgba(121,255,217,1)'></td>
+ <td width='1' style='background-color: rgba(141,255,218,1)'></td>
+ <td width='1' style='background-color: rgba(157,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(171,255,220,1)'></td>
+ <td width='1' style='background-color: rgba(184,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,220,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,216,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(196,255,205,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(195,255,205,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(203,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,175,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,165,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,154,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,127,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,112,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,235,75,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,49,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,203,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,233,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(106,255,220,1)'></td>
+ <td width='1' style='background-color: rgba(129,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,222,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,225,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,226,1)'></td>
+ <td width='1' style='background-color: rgba(200,255,226,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,176,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,164,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,153,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,126,1)'></td>
+ <td width='1' style='background-color: rgba(255,235,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,225,93,1)'></td>
+ <td width='1' style='background-color: rgba(255,215,73,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(98,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(86,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(114,255,225,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,226,1)'></td>
+ <td width='1' style='background-color: rgba(154,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(170,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(184,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,230,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(208,255,231,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(207,255,231,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(214,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,220,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,205,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,175,1)'></td>
+ <td width='1' style='background-color: rgba(253,254,163,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,152,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,139,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,125,1)'></td>
+ <td width='1' style='background-color: rgba(255,216,109,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,207,92,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,207,91,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,196,71,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,187,50,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,187,49,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,236,220,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,251,1)'></td>
+ <td width='1' style='background-color: rgba(55,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(95,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(120,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(141,255,231,1)'></td>
+ <td width='1' style='background-color: rgba(159,255,232,1)'></td>
+ <td width='1' style='background-color: rgba(176,255,232,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,235,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,236,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,235,1)'></td>
+ <td width='1' style='background-color: rgba(223,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,214,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(253,254,185,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,237,163,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,138,1)'></td>
+ <td width='1' style='background-color: rgba(255,208,124,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,108,1)'></td>
+ <td width='1' style='background-color: rgba(255,187,90,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,176,69,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,175,69,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,172,81,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(200,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,233,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(127,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,235,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,236,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,237,1)'></td>
+ <td width='1' style='background-color: rgba(195,255,238,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(208,255,238,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(207,255,238,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(219,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(229,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,214,1)'></td>
+ <td width='1' style='background-color: rgba(253,254,205,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,195,1)'></td>
+ <td width='1' style='background-color: rgba(255,237,185,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,162,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,149,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,136,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,189,121,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,188,121,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,178,105,1)'></td>
+ <td width='1' style='background-color: rgba(255,166,86,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,64,1)'></td>
+ <td width='1' style='background-color: rgba(253,149,79,1)'></td>
+ <td width='1' style='background-color: rgba(253,237,232,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(170,255,245,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(108,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(131,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(151,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(184,255,241,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,242,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,243,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,244,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,245,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,242,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,232,1)'></td>
+ <td width='1' style='background-color: rgba(253,254,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,214,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,205,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,194,1)'></td>
+ <td width='1' style='background-color: rgba(255,220,184,1)'></td>
+ <td width='1' style='background-color: rgba(255,210,173,1)'></td>
+ <td width='1' style='background-color: rgba(255,200,160,1)'></td>
+ <td width='1' style='background-color: rgba(255,190,148,1)'></td>
+ <td width='1' style='background-color: rgba(255,179,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,167,120,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,104,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,85,1)'></td>
+ <td width='1' style='background-color: rgba(255,125,64,1)'></td>
+ <td width='1' style='background-color: rgba(252,127,86,1)'></td>
+ <td width='1' style='background-color: rgba(254,241,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(133,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(83,255,244,1)'></td>
+ <td width='1' style='background-color: rgba(113,255,245,1)'></td>
+ <td width='1' style='background-color: rgba(135,255,245,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(215,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,249,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(253,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(255,248,232,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,222,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,213,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,203,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,194,1)'></td>
+ <td width='1' style='background-color: rgba(255,200,183,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,189,172,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,188,172,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,176,160,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,149,1)'></td>
+ <td width='1' style='background-color: rgba(255,148,137,1)'></td>
+ <td width='1' style='background-color: rgba(255,132,125,1)'></td>
+ <td width='1' style='background-color: rgba(255,114,112,1)'></td>
+ <td width='1' style='background-color: rgba(255,95,96,1)'></td>
+ <td width='1' style='background-color: rgba(255,71,81,1)'></td>
+ <td width='1' style='background-color: rgba(255,110,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,243,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,250,1)'></td>
+ <td width='1' style='background-color: rgba(88,255,250,1)'></td>
+ <td width='1' style='background-color: rgba(116,255,251,1)'></td>
+ <td width='1' style='background-color: rgba(139,255,251,1)'></td>
+ <td width='1' style='background-color: rgba(158,255,251,1)'></td>
+ <td width='1' style='background-color: rgba(175,255,252,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,252,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,252,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,253,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,253,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,254,1)'></td>
+ <td width='1' style='background-color: rgba(252,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,249,248,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,234,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,219,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,203,212,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,203,211,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,192,204,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,196,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,170,189,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,170,188,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,159,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,171,1)'></td>
+ <td width='1' style='background-color: rgba(255,133,162,1)'></td>
+ <td width='1' style='background-color: rgba(255,118,153,1)'></td>
+ <td width='1' style='background-color: rgba(255,101,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,83,132,1)'></td>
+ <td width='1' style='background-color: rgba(255,59,120,1)'></td>
+ <td width='1' style='background-color: rgba(255,121,152,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,249,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(55,253,254,1)'></td>
+ <td width='1' style='background-color: rgba(93,253,254,1)'></td>
+ <td width='1' style='background-color: rgba(120,253,254,1)'></td>
+ <td width='1' style='background-color: rgba(142,252,254,1)'></td>
+ <td width='1' style='background-color: rgba(161,252,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(206,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,250,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,249,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,246,255,1)'></td>
+ <td width='1' style='background-color: rgba(253,238,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,248,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,220,237,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,232,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,210,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,203,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,197,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,190,1)'></td>
+ <td width='1' style='background-color: rgba(255,142,182,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,157,1)'></td>
+ <td width='1' style='background-color: rgba(255,79,147,1)'></td>
+ <td width='1' style='background-color: rgba(255,56,136,1)'></td>
+ <td width='1' style='background-color: rgba(255,138,172,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,251,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(225,253,255,1)'></td>
+ <td width='1' style='background-color: rgba(61,246,254,1)'></td>
+ <td width='1' style='background-color: rgba(98,246,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,246,255,1)'></td>
+ <td width='1' style='background-color: rgba(144,246,255,1)'></td>
+ <td width='1' style='background-color: rgba(163,245,255,1)'></td>
+ <td width='1' style='background-color: rgba(179,244,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,244,255,1)'></td>
+ <td width='1' style='background-color: rgba(207,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,241,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(253,218,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,246,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,233,1)'></td>
+ <td width='1' style='background-color: rgba(255,190,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,166,210,1)'></td>
+ <td width='1' style='background-color: rgba(255,158,204,1)'></td>
+ <td width='1' style='background-color: rgba(255,148,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,119,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,108,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,96,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,83,160,1)'></td>
+ <td width='1' style='background-color: rgba(255,66,154,1)'></td>
+ <td width='1' style='background-color: rgba(255,56,148,1)'></td>
+ <td width='1' style='background-color: rgba(255,148,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,235,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(210,250,255,1)'></td>
+ <td width='1' style='background-color: rgba(66,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(126,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(146,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(163,237,255,1)'></td>
+ <td width='1' style='background-color: rgba(179,236,255,1)'></td>
+ <td width='1' style='background-color: rgba(193,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(206,232,255,1)'></td>
+ <td width='1' style='background-color: rgba(216,223,255,1)'></td>
+ <td width='1' style='background-color: rgba(232,210,255,1)'></td>
+ <td width='1' style='background-color: rgba(245,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(252,195,252,1)'></td>
+ <td width='1' style='background-color: rgba(255,187,246,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,218,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,211,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,205,1)'></td>
+ <td width='1' style='background-color: rgba(255,126,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,104,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,90,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,77,173,1)'></td>
+ <td width='1' style='background-color: rgba(255,59,167,1)'></td>
+ <td width='1' style='background-color: rgba(254,42,158,1)'></td>
+ <td width='1' style='background-color: rgba(251,95,163,1)'></td>
+ <td width='1' style='background-color: rgba(252,185,207,1)'></td>
+ <td width='1' style='background-color: rgba(254,241,245,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(199,246,255,1)'></td>
+ <td width='1' style='background-color: rgba(68,232,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(125,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,229,255,1)'></td>
+ <td width='1' style='background-color: rgba(163,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(191,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(201,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(234,185,255,1)'></td>
+ <td width='1' style='background-color: rgba(245,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,170,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,160,244,1)'></td>
+ <td width='1' style='background-color: rgba(255,152,236,1)'></td>
+ <td width='1' style='background-color: rgba(255,143,228,1)'></td>
+ <td width='1' style='background-color: rgba(255,134,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,124,214,1)'></td>
+ <td width='1' style='background-color: rgba(255,113,208,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,200,1)'></td>
+ <td width='1' style='background-color: rgba(255,86,194,1)'></td>
+ <td width='1' style='background-color: rgba(255,71,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,53,180,1)'></td>
+ <td width='1' style='background-color: rgba(252,34,170,1)'></td>
+ <td width='1' style='background-color: rgba(245,34,155,1)'></td>
+ <td width='1' style='background-color: rgba(244,146,185,1)'></td>
+ <td width='1' style='background-color: rgba(249,216,226,1)'></td>
+ <td width='1' style='background-color: rgba(255,253,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(200,242,255,1)'></td>
+ <td width='1' style='background-color: rgba(66,223,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(125,220,255,1)'></td>
+ <td width='1' style='background-color: rgba(144,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(160,215,255,1)'></td>
+ <td width='1' style='background-color: rgba(174,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(185,197,255,1)'></td>
+ <td width='1' style='background-color: rgba(205,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(223,167,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(246,150,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,140,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,243,1)'></td>
+ <td width='1' style='background-color: rgba(255,119,235,1)'></td>
+ <td width='1' style='background-color: rgba(255,108,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,96,219,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,83,212,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,83,211,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,69,205,1)'></td>
+ <td width='1' style='background-color: rgba(255,50,196,1)'></td>
+ <td width='1' style='background-color: rgba(250,28,184,1)'></td>
+ <td width='1' style='background-color: rgba(240,13,164,1)'></td>
+ <td width='1' style='background-color: rgba(231,90,159,1)'></td>
+ <td width='1' style='background-color: rgba(239,185,203,1)'></td>
+ <td width='1' style='background-color: rgba(251,241,244,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(202,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(66,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(98,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(122,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(141,205,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(167,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,161,255,1)'></td>
+ <td width='1' style='background-color: rgba(210,147,255,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(225,137,255,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(224,137,255,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(236,128,255,1)'></td>
+ <td width='1' style='background-color: rgba(246,118,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,105,249,1)'></td>
+ <td width='1' style='background-color: rgba(254,92,241,1)'></td>
+ <td width='1' style='background-color: rgba(255,77,234,1)'></td>
+ <td width='1' style='background-color: rgba(255,61,226,1)'></td>
+ <td width='1' style='background-color: rgba(254,42,215,1)'></td>
+ <td width='1' style='background-color: rgba(248,22,200,1)'></td>
+ <td width='1' style='background-color: rgba(237,0,178,1)'></td>
+ <td width='1' style='background-color: rgba(220,28,149,1)'></td>
+ <td width='1' style='background-color: rgba(223,146,177,1)'></td>
+ <td width='1' style='background-color: rgba(240,216,223,1)'></td>
+ <td width='1' style='background-color: rgba(254,253,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(214,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(61,201,255,1)'></td>
+ <td width='1' style='background-color: rgba(95,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(118,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(134,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(147,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(170,142,255,1)'></td>
+ <td width='1' style='background-color: rgba(197,125,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,113,255,1)'></td>
+ <td width='1' style='background-color: rgba(226,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(237,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(246,75,254,1)'></td>
+ <td width='1' style='background-color: rgba(250,56,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,34,237,1)'></td>
+ <td width='1' style='background-color: rgba(245,13,219,1)'></td>
+ <td width='1' style='background-color: rgba(232,0,193,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,159,1)'></td>
+ <td width='1' style='background-color: rgba(203,90,149,1)'></td>
+ <td width='1' style='background-color: rgba(223,185,199,1)'></td>
+ <td width='1' style='background-color: rgba(248,241,243,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(230,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(56,187,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,181,255,1)'></td>
+ <td width='1' style='background-color: rgba(108,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(124,151,255,1)'></td>
+ <td width='1' style='background-color: rgba(149,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(182,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(200,83,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,69,255,1)'></td>
+ <td width='1' style='background-color: rgba(226,50,255,1)'></td>
+ <td width='1' style='background-color: rgba(234,34,251,1)'></td>
+ <td width='1' style='background-color: rgba(234,13,237,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,210,1)'></td>
+ <td width='1' style='background-color: rgba(206,0,175,1)'></td>
+ <td width='1' style='background-color: rgba(185,28,140,1)'></td>
+ <td width='1' style='background-color: rgba(200,146,170,1)'></td>
+ <td width='1' style='background-color: rgba(232,215,220,1)'></td>
+ <td width='1' style='background-color: rgba(254,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(252,253,255,1)'></td>
+ <td width='1' style='background-color: rgba(90,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(93,132,255,1)'></td>
+ <td width='1' style='background-color: rgba(126,98,255,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(164,69,255,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(163,69,255,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(185,42,254,1)'></td>
+ <td width='1' style='background-color: rgba(195,22,248,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,236,1)'></td>
+ <td width='1' style='background-color: rgba(197,0,218,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,193,1)'></td>
+ <td width='1' style='background-color: rgba(173,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(169,90,140,1)'></td>
+ <td width='1' style='background-color: rgba(208,185,194,1)'></td>
+ <td width='1' style='background-color: rgba(245,241,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(216,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(77,124,255,1)'></td>
+ <td width='1' style='background-color: rgba(86,71,252,1)'></td>
+ <td width='1' style='background-color: rgba(120,42,244,1)'></td>
+ <td width='1' style='background-color: rgba(134,22,230,1)'></td>
+ <td width='1' style='background-color: rgba(136,13,209,1)'></td>
+ <td width='1' style='background-color: rgba(135,0,186,1)'></td>
+ <td width='1' style='background-color: rgba(133,0,159,1)'></td>
+ <td width='1' style='background-color: rgba(130,28,132,1)'></td>
+ <td width='1' style='background-color: rgba(174,146,165,1)'></td>
+ <td width='1' style='background-color: rgba(223,216,219,1)'></td>
+ <td width='1' style='background-color: rgba(254,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,240,252,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,250,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,239,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,230,1)'></td>
+ <td width='1' style='background-color: rgba(222,221,227,1)'></td>
+ <td width='1' style='background-color: rgba(222,221,223,1)'></td>
+ <td width='1' style='background-color: rgba(244,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/ccwn2c08.png b/image/test/reftest/pngsuite-ancillary/ccwn2c08.png
new file mode 100644
index 0000000000..47c24817b7
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ccwn2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/ccwn3p08.html b/image/test/reftest/pngsuite-ancillary/ccwn3p08.html
new file mode 100644
index 0000000000..52e636eaad
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ccwn3p08.html
@@ -0,0 +1,1272 @@
+<html>
+<head>
+<link rel="stylesheet" href="../ImageDocument.css">
+<script src="qcms-asm-check.js" type="application/ecmascript"></script>
+<!-- generated with:
+import png
+import sys
+print """<html>
+<head>
+<script src="qcms-asm-check.js" type="application/ecmascript"></script>
+<!-""" + """- generated with:"""
+print open(__file__).read()
+print "-" + """->
+</head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>"""
+r1 = png.Reader(file=open(sys.argv[1]))
+r2 = png.Reader(file=open(sys.argv[2]))
+(data1, data2) = (r1.asDirect(), r2.asDirect())
+(pixels1, pixels2) = (list(data1[2])[8:32+8], list(data2[2])[8:32+8])
+planes = data1[3]['planes']
+for (line1, line2) in zip(pixels1, pixels2):
+ r1, g1, b1 = (line1[0::planes][8:32+8], line1[1::planes][8:32+8], line1[2::planes][8:32+8])
+ r2, g2, b2 = (line2[0::planes][8:32+8], line2[1::planes][8:32+8], line2[2::planes][8:32+8])
+ print "<tr height='1'>"
+ for (pixel1, pixel2) in zip(zip(r1,g1,b1), zip(r2,g2,b2)):
+ if pixel1[0] == pixel2[0] and pixel1[1] == pixel2[1] and pixel1[2] == pixel2[2]:
+ print " <td width='1' style='background-color: rgba(%d,%d,%d,1)'></td>" % (pixel1[0], pixel1[1], pixel1[2])
+ else:
+ print """<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(%d,%d,%d,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(%d,%d,%d,1)'></td>");
+}
+</script>""" % (pixel1[0], pixel1[1], pixel1[2], pixel2[0], pixel2[1], pixel2[2])
+ print "</tr>"
+print """</table>
+</body></html>"""
+
+-->
+</head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,232,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,190,1)'></td>
+ <td width='1' style='background-color: rgba(114,255,164,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,187,1)'></td>
+ <td width='1' style='background-color: rgba(216,255,222,1)'></td>
+ <td width='1' style='background-color: rgba(253,255,253,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(71,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(71,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,120,1)'></td>
+ <td width='1' style='background-color: rgba(134,255,127,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,232,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(64,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(64,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(86,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(71,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,120,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,120,1)'></td>
+ <td width='1' style='background-color: rgba(127,255,95,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,188,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,243,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,187,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(77,255,185,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(77,255,184,1)'></td>");
+}
+</script>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(77,255,185,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(77,255,184,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(101,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(114,255,164,1)'></td>
+ <td width='1' style='background-color: rgba(114,255,164,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,120,1)'></td>
+ <td width='1' style='background-color: rgba(127,255,95,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(163,255,92,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(163,255,91,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(199,255,148,1)'></td>
+ <td width='1' style='background-color: rgba(253,255,253,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,206,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(73,255,185,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(73,255,184,1)'></td>");
+}
+</script>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(77,255,185,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(77,255,184,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(116,255,190,1)'></td>
+ <td width='1' style='background-color: rgba(116,255,190,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,169,1)'></td>
+ <td width='1' style='background-color: rgba(114,255,164,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(134,255,127,1)'></td>
+ <td width='1' style='background-color: rgba(153,255,104,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(163,255,92,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(163,255,91,1)'></td>");
+}
+</script>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(163,255,92,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(163,255,91,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(205,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(253,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,187,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,193,1)'></td>
+ <td width='1' style='background-color: rgba(116,255,190,1)'></td>
+ <td width='1' style='background-color: rgba(134,255,195,1)'></td>
+ <td width='1' style='background-color: rgba(151,255,182,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,169,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(134,255,127,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(163,255,92,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(163,255,91,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(186,255,96,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,96,1)'></td>
+ <td width='1' style='background-color: rgba(195,255,79,1)'></td>
+ <td width='1' style='background-color: rgba(217,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(253,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(126,255,215,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(134,255,195,1)'></td>
+ <td width='1' style='background-color: rgba(134,255,195,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(151,255,182,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,169,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,96,1)'></td>
+ <td width='1' style='background-color: rgba(195,255,79,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,253,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,243,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,207,1)'></td>
+ <td width='1' style='background-color: rgba(91,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,208,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,208,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,208,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,190,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,190,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,187,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,121,1)'></td>
+ <td width='1' style='background-color: rgba(217,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,79,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,79,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,253,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,207,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,205,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,208,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,208,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,208,1)'></td>
+ <td width='1' style='background-color: rgba(165,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(176,255,209,1)'></td>
+ <td width='1' style='background-color: rgba(176,255,209,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,187,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,178,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,148,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,121,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,114,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,79,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,66,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,66,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(248,255,251,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,216,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,210,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,208,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,216,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,215,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,215,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(176,255,209,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,170,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,170,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,148,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(251,254,95,1)'></td>
+ <td width='1' style='background-color: rgba(251,254,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,96,1)'></td>
+ <td width='1' style='background-color: rgba(254,249,185,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,242,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,216,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,210,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,220,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,216,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,215,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,194,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,188,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,170,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,148,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,148,1)'></td>
+ <td width='1' style='background-color: rgba(241,255,147,1)'></td>
+ <td width='1' style='background-color: rgba(250,254,133,1)'></td>
+ <td width='1' style='background-color: rgba(251,254,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,96,1)'></td>
+ <td width='1' style='background-color: rgba(255,225,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,225,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,196,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(170,255,233,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,216,1)'></td>
+ <td width='1' style='background-color: rgba(114,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(134,255,222,1)'></td>
+ <td width='1' style='background-color: rgba(142,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(179,255,231,1)'></td>
+ <td width='1' style='background-color: rgba(187,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,218,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,190,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,190,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(250,254,133,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,96,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,117,1)'></td>
+ <td width='1' style='background-color: rgba(255,225,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,93,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,93,1)'></td>
+ <td width='1' style='background-color: rgba(255,231,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(106,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,216,1)'></td>
+ <td width='1' style='background-color: rgba(114,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(134,255,222,1)'></td>
+ <td width='1' style='background-color: rgba(142,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(187,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(211,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(211,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(216,255,222,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,195,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,168,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,117,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,93,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,197,92,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,197,91,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,179,66,1)'></td>
+ <td width='1' style='background-color: rgba(254,236,226,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(61,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(106,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(106,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(142,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(179,255,231,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,236,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(211,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,232,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(254,249,185,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,170,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,170,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,125,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,119,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,197,92,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,197,91,1)'></td>");
+}
+</script>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,197,92,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,197,91,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,179,66,1)'></td>
+ <td width='1' style='background-color: rgba(255,176,88,1)'></td>
+ <td width='1' style='background-color: rgba(254,236,226,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(61,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(106,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(135,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(154,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(167,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(185,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,236,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,242,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,243,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,233,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(253,254,214,1)'></td>
+ <td width='1' style='background-color: rgba(253,254,214,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,196,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,229,185,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,229,184,1)'></td>");
+}
+</script>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,229,185,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,229,184,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,220,184,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,148,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,148,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,197,92,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,197,91,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,176,88,1)'></td>
+ <td width='1' style='background-color: rgba(255,176,88,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,106,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,106,1)'></td>
+ <td width='1' style='background-color: rgba(254,236,226,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(169,254,251,1)'></td>
+ <td width='1' style='background-color: rgba(66,254,246,1)'></td>
+ <td width='1' style='background-color: rgba(108,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(135,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(154,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(167,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(185,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,242,1)'></td>
+ <td width='1' style='background-color: rgba(213,253,246,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(237,253,249,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(255,248,223,1)'></td>
+ <td width='1' style='background-color: rgba(253,254,214,1)'></td>
+ <td width='1' style='background-color: rgba(255,231,206,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,229,185,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,229,184,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,220,184,1)'></td>
+ <td width='1' style='background-color: rgba(255,220,184,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,148,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,189,148,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,188,148,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,178,148,1)'></td>
+ <td width='1' style='background-color: rgba(255,167,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,106,1)'></td>
+ <td width='1' style='background-color: rgba(255,132,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,132,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,132,95,1)'></td>
+ <td width='1' style='background-color: rgba(254,241,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(79,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(98,255,245,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(154,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(169,254,251,1)'></td>
+ <td width='1' style='background-color: rgba(185,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(213,253,246,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(237,253,249,1)'></td>
+ <td width='1' style='background-color: rgba(248,255,251,1)'></td>
+ <td width='1' style='background-color: rgba(253,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(255,248,223,1)'></td>
+ <td width='1' style='background-color: rgba(254,236,226,1)'></td>
+ <td width='1' style='background-color: rgba(255,231,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,231,206,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,212,196,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,211,196,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,202,198,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,185,155,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,185,154,1)'></td>");
+}
+</script>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(255,185,155,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(255,185,154,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(255,167,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,167,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,108,125,1)'></td>
+ <td width='1' style='background-color: rgba(255,108,125,1)'></td>
+ <td width='1' style='background-color: rgba(255,88,115,1)'></td>
+ <td width='1' style='background-color: rgba(255,88,115,1)'></td>
+ <td width='1' style='background-color: rgba(255,108,125,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(79,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(79,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(109,250,254,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(154,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(169,254,251,1)'></td>
+ <td width='1' style='background-color: rgba(185,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(222,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(241,255,254,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,248,249,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,191,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,198,1)'></td>
+ <td width='1' style='background-color: rgba(246,185,205,1)'></td>
+ <td width='1' style='background-color: rgba(255,149,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,149,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,126,163,1)'></td>
+ <td width='1' style='background-color: rgba(255,77,134,1)'></td>
+ <td width='1' style='background-color: rgba(255,77,134,1)'></td>
+ <td width='1' style='background-color: rgba(255,56,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,126,163,1)'></td>
+ <td width='1' style='background-color: rgba(255,248,249,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(241,255,254,1)'></td>
+ <td width='1' style='background-color: rgba(79,250,254,1)'></td>
+ <td width='1' style='background-color: rgba(79,250,254,1)'></td>
+ <td width='1' style='background-color: rgba(109,250,254,1)'></td>
+ <td width='1' style='background-color: rgba(133,249,254,1)'></td>
+ <td width='1' style='background-color: rgba(169,254,251,1)'></td>
+ <td width='1' style='background-color: rgba(185,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(185,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,248,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(246,248,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,240,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,244,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,238,1)'></td>
+ <td width='1' style='background-color: rgba(251,222,240,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,233,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,233,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,191,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,191,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,210,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,210,1)'></td>
+ <td width='1' style='background-color: rgba(255,149,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,149,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,118,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,162,1)'></td>
+ <td width='1' style='background-color: rgba(255,77,134,1)'></td>
+ <td width='1' style='background-color: rgba(255,56,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,248,249,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(222,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(79,250,254,1)'></td>
+ <td width='1' style='background-color: rgba(109,250,254,1)'></td>
+ <td width='1' style='background-color: rgba(133,249,254,1)'></td>
+ <td width='1' style='background-color: rgba(145,242,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,242,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,242,255,1)'></td>
+ <td width='1' style='background-color: rgba(197,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(205,241,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,241,255,1)'></td>
+ <td width='1' style='background-color: rgba(229,232,247,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,216,240,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,233,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,227,1)'></td>
+ <td width='1' style='background-color: rgba(254,189,232,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,170,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,210,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,211,1)'></td>
+ <td width='1' style='background-color: rgba(255,137,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,137,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,137,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,112,170,1)'></td>
+ <td width='1' style='background-color: rgba(255,112,170,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,162,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,162,1)'></td>
+ <td width='1' style='background-color: rgba(255,56,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,56,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,149,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,244,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(203,248,255,1)'></td>
+ <td width='1' style='background-color: rgba(79,234,255,1)'></td>
+ <td width='1' style='background-color: rgba(114,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(114,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,242,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,242,255,1)'></td>
+ <td width='1' style='background-color: rgba(173,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(197,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(197,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(216,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,209,239,1)'></td>
+ <td width='1' style='background-color: rgba(242,209,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,185,234,1)'></td>
+ <td width='1' style='background-color: rgba(255,185,234,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,170,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,148,216,1)'></td>
+ <td width='1' style='background-color: rgba(255,148,216,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,213,1)'></td>
+ <td width='1' style='background-color: rgba(255,120,196,1)'></td>
+ <td width='1' style='background-color: rgba(255,120,196,1)'></td>
+ <td width='1' style='background-color: rgba(255,92,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,66,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,66,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,56,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,56,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,162,1)'></td>
+ <td width='1' style='background-color: rgba(246,185,205,1)'></td>
+ <td width='1' style='background-color: rgba(254,241,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(197,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(79,234,255,1)'></td>
+ <td width='1' style='background-color: rgba(79,234,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(173,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(173,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(197,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(226,188,238,1)'></td>
+ <td width='1' style='background-color: rgba(234,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(234,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(253,165,247,1)'></td>
+ <td width='1' style='background-color: rgba(253,165,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,236,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,236,1)'></td>
+ <td width='1' style='background-color: rgba(255,121,225,1)'></td>
+ <td width='1' style='background-color: rgba(251,125,213,1)'></td>
+ <td width='1' style='background-color: rgba(255,108,208,1)'></td>
+ <td width='1' style='background-color: rgba(255,108,208,1)'></td>
+ <td width='1' style='background-color: rgba(255,92,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,66,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,66,180,1)'></td>
+ <td width='1' style='background-color: rgba(251,28,177,1)'></td>
+ <td width='1' style='background-color: rgba(242,22,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,149,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,233,1)'></td>
+ <td width='1' style='background-color: rgba(254,253,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(197,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(151,210,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(234,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(234,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(253,165,247,1)'></td>
+ <td width='1' style='background-color: rgba(253,165,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,236,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,236,1)'></td>
+ <td width='1' style='background-color: rgba(255,121,225,1)'></td>
+ <td width='1' style='background-color: rgba(255,90,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,90,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,59,200,1)'></td>
+ <td width='1' style='background-color: rgba(255,59,200,1)'></td>
+ <td width='1' style='background-color: rgba(251,28,177,1)'></td>
+ <td width='1' style='background-color: rgba(242,22,159,1)'></td>
+ <td width='1' style='background-color: rgba(229,13,174,1)'></td>
+ <td width='1' style='background-color: rgba(246,185,205,1)'></td>
+ <td width='1' style='background-color: rgba(254,241,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(205,241,255,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(83,212,255,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(83,211,255,1)'></td>");
+}
+</script>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(83,212,255,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(83,211,255,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(98,205,255,1)'></td>
+ <td width='1' style='background-color: rgba(151,210,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,126,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,126,255,1)'></td>
+ <td width='1' style='background-color: rgba(241,122,255,1)'></td>
+ <td width='1' style='background-color: rgba(241,122,255,1)'></td>
+ <td width='1' style='background-color: rgba(241,122,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,85,238,1)'></td>
+ <td width='1' style='background-color: rgba(254,85,238,1)'></td>
+ <td width='1' style='background-color: rgba(254,53,220,1)'></td>
+ <td width='1' style='background-color: rgba(254,53,220,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(247,13,210,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(246,13,210,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(229,13,174,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,167,1)'></td>
+ <td width='1' style='background-color: rgba(244,148,155,1)'></td>
+ <td width='1' style='background-color: rgba(229,214,232,1)'></td>
+ <td width='1' style='background-color: rgba(254,253,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(221,241,255,1)'></td>
+ <td width='1' style='background-color: rgba(98,205,255,1)'></td>
+ <td width='1' style='background-color: rgba(93,193,255,1)'></td>
+ <td width='1' style='background-color: rgba(93,193,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(119,158,255,1)'></td>
+ <td width='1' style='background-color: rgba(184,133,255,1)'></td>
+ <td width='1' style='background-color: rgba(184,133,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,126,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,126,255,1)'></td>
+ <td width='1' style='background-color: rgba(241,81,254,1)'></td>
+ <td width='1' style='background-color: rgba(241,81,254,1)'></td>
+ <td width='1' style='background-color: rgba(242,34,244,1)'></td>
+ <td width='1' style='background-color: rgba(254,85,238,1)'></td>
+<script type="application/ecmascript">
+if (qcms_has_assembly) {
+ document.write("<td width='1' style='background-color: rgba(247,13,210,1)'></td>");
+} else {
+ document.write("<td width='1' style='background-color: rgba(246,13,210,1)'></td>");
+}
+</script>
+ <td width='1' style='background-color: rgba(229,13,174,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,167,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,167,1)'></td>
+ <td width='1' style='background-color: rgba(246,185,205,1)'></td>
+ <td width='1' style='background-color: rgba(244,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(221,241,255,1)'></td>
+ <td width='1' style='background-color: rgba(93,193,255,1)'></td>
+ <td width='1' style='background-color: rgba(95,176,255,1)'></td>
+ <td width='1' style='background-color: rgba(95,176,255,1)'></td>
+ <td width='1' style='background-color: rgba(119,158,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,110,255,1)'></td>
+ <td width='1' style='background-color: rgba(184,133,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,126,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,126,255,1)'></td>
+ <td width='1' style='background-color: rgba(241,81,254,1)'></td>
+ <td width='1' style='background-color: rgba(241,81,254,1)'></td>
+ <td width='1' style='background-color: rgba(228,28,235,1)'></td>
+ <td width='1' style='background-color: rgba(223,86,229,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,167,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,167,1)'></td>
+ <td width='1' style='background-color: rgba(196,146,202,1)'></td>
+ <td width='1' style='background-color: rgba(229,214,232,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(253,253,254,1)'></td>
+ <td width='1' style='background-color: rgba(95,176,255,1)'></td>
+ <td width='1' style='background-color: rgba(95,176,255,1)'></td>
+ <td width='1' style='background-color: rgba(85,128,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,110,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,110,255,1)'></td>
+ <td width='1' style='background-color: rgba(184,133,255,1)'></td>
+ <td width='1' style='background-color: rgba(198,0,227,1)'></td>
+ <td width='1' style='background-color: rgba(198,0,227,1)'></td>
+ <td width='1' style='background-color: rgba(198,0,227,1)'></td>
+ <td width='1' style='background-color: rgba(187,0,203,1)'></td>
+ <td width='1' style='background-color: rgba(132,13,161,1)'></td>
+ <td width='1' style='background-color: rgba(132,13,161,1)'></td>
+ <td width='1' style='background-color: rgba(196,146,202,1)'></td>
+ <td width='1' style='background-color: rgba(244,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(216,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(85,128,255,1)'></td>
+ <td width='1' style='background-color: rgba(85,128,255,1)'></td>
+ <td width='1' style='background-color: rgba(130,28,228,1)'></td>
+ <td width='1' style='background-color: rgba(130,28,228,1)'></td>
+ <td width='1' style='background-color: rgba(146,77,224,1)'></td>
+ <td width='1' style='background-color: rgba(132,13,161,1)'></td>
+ <td width='1' style='background-color: rgba(132,13,161,1)'></td>
+ <td width='1' style='background-color: rgba(132,13,161,1)'></td>
+ <td width='1' style='background-color: rgba(196,146,202,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,227,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,254,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,251,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,251,1)'></td>
+ <td width='1' style='background-color: rgba(229,232,247,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,227,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,227,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,227,1)'></td>
+ <td width='1' style='background-color: rgba(244,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/ccwn3p08.png b/image/test/reftest/pngsuite-ancillary/ccwn3p08.png
new file mode 100644
index 0000000000..8bb2c10981
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ccwn3p08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/cdfn2c08.html b/image/test/reftest/pngsuite-ancillary/cdfn2c08.html
new file mode 100644
index 0000000000..aaae670ec4
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cdfn2c08.html
@@ -0,0 +1,326 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='8' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,247,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(239,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,212,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(230,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(180,102,247,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(230,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,221,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(192,102,230,1)'></td>
+ <td width='1' style='background-color: rgba(102,247,168,1)'></td>
+ <td width='1' style='background-color: rgba(230,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,212,221,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,102,230,1)'></td>
+ <td width='1' style='background-color: rgba(102,247,168,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,212,221,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(192,102,230,1)'></td>
+ <td width='1' style='background-color: rgba(102,247,168,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(192,102,239,1)'></td>
+ <td width='1' style='background-color: rgba(102,247,168,1)'></td>
+ <td width='1' style='background-color: rgba(230,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(155,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(230,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,212,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(230,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(239,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,221,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/cdfn2c08.png b/image/test/reftest/pngsuite-ancillary/cdfn2c08.png
new file mode 100644
index 0000000000..559e5261e7
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cdfn2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/cdhn2c08.html b/image/test/reftest/pngsuite-ancillary/cdhn2c08.html
new file mode 100644
index 0000000000..d56ebf2e1b
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cdhn2c08.html
@@ -0,0 +1,278 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='8'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,74,230,1)'></td>
+ <td width='1' style='background-color: rgba(221,74,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,74,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,74,221,1)'></td>
+ <td width='1' style='background-color: rgba(202,74,239,1)'></td>
+ <td width='1' style='background-color: rgba(123,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/cdhn2c08.png b/image/test/reftest/pngsuite-ancillary/cdhn2c08.png
new file mode 100644
index 0000000000..3e07e8ecbd
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cdhn2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/cdsn2c08.html b/image/test/reftest/pngsuite-ancillary/cdsn2c08.html
new file mode 100644
index 0000000000..3ba83a6f5a
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cdsn2c08.html
@@ -0,0 +1,86 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='8' height='8'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,212,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(247,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(180,102,239,1)'></td>
+ <td width='1' style='background-color: rgba(102,247,155,1)'></td>
+ <td width='1' style='background-color: rgba(230,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(202,74,230,1)'></td>
+ <td width='1' style='background-color: rgba(155,123,247,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(230,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,192,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(247,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/cdsn2c08.png b/image/test/reftest/pngsuite-ancillary/cdsn2c08.png
new file mode 100644
index 0000000000..076c32cc08
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cdsn2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/cdun2c08.html b/image/test/reftest/pngsuite-ancillary/cdun2c08.html
new file mode 100644
index 0000000000..b782337185
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cdun2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,239,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,239,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/cdun2c08.png b/image/test/reftest/pngsuite-ancillary/cdun2c08.png
new file mode 100644
index 0000000000..846033be6b
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cdun2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/ch1n3p04.html b/image/test/reftest/pngsuite-ancillary/ch1n3p04.html
new file mode 100644
index 0000000000..dc2a121de2
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ch1n3p04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/ch1n3p04.png b/image/test/reftest/pngsuite-ancillary/ch1n3p04.png
new file mode 100644
index 0000000000..17cd12dfc9
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ch1n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/ch2n3p08.html b/image/test/reftest/pngsuite-ancillary/ch2n3p08.html
new file mode 100644
index 0000000000..78b72c61c6
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ch2n3p08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(21,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,28,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,28,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,28,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,28,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,21,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(59,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(59,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(59,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(59,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,74,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(123,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,123,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,140,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,112,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,112,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,112,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,112,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(168,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,122,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,122,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,122,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,122,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(122,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(122,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(122,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(122,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,168,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(192,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,192,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(202,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,153,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,153,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,153,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,153,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(221,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,160,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,160,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,160,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,160,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(160,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(160,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(160,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(160,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(230,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,238,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/ch2n3p08.png b/image/test/reftest/pngsuite-ancillary/ch2n3p08.png
new file mode 100644
index 0000000000..25c17987a7
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ch2n3p08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/cm0n0g04.html b/image/test/reftest/pngsuite-ancillary/cm0n0g04.html
new file mode 100644
index 0000000000..25d3abca33
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cm0n0g04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/cm0n0g04.png b/image/test/reftest/pngsuite-ancillary/cm0n0g04.png
new file mode 100644
index 0000000000..9fba5db3b8
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cm0n0g04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/cm7n0g04.html b/image/test/reftest/pngsuite-ancillary/cm7n0g04.html
new file mode 100644
index 0000000000..25d3abca33
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cm7n0g04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/cm7n0g04.png b/image/test/reftest/pngsuite-ancillary/cm7n0g04.png
new file mode 100644
index 0000000000..f7dc46e685
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cm7n0g04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/cm9n0g04.html b/image/test/reftest/pngsuite-ancillary/cm9n0g04.html
new file mode 100644
index 0000000000..25d3abca33
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cm9n0g04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/cm9n0g04.png b/image/test/reftest/pngsuite-ancillary/cm9n0g04.png
new file mode 100644
index 0000000000..dd70911adc
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cm9n0g04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/cs3n2c16.html b/image/test/reftest/pngsuite-ancillary/cs3n2c16.html
new file mode 100644
index 0000000000..bc4ab1488f
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cs3n2c16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,99,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,136,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,163,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/cs3n2c16.png b/image/test/reftest/pngsuite-ancillary/cs3n2c16.png
new file mode 100644
index 0000000000..bf5fd20a20
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cs3n2c16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/cs3n3p08.html b/image/test/reftest/pngsuite-ancillary/cs3n3p08.html
new file mode 100644
index 0000000000..21557a4004
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cs3n3p08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,105,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,144,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,173,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,198,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,219,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,238,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,219,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,198,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,144,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/cs3n3p08.png b/image/test/reftest/pngsuite-ancillary/cs3n3p08.png
new file mode 100644
index 0000000000..f4a66237bf
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cs3n3p08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/cs5n2c08.html b/image/test/reftest/pngsuite-ancillary/cs5n2c08.html
new file mode 100644
index 0000000000..d1642a1bf5
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cs5n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/cs5n2c08.png b/image/test/reftest/pngsuite-ancillary/cs5n2c08.png
new file mode 100644
index 0000000000..40f947c33e
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cs5n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/cs5n3p08.html b/image/test/reftest/pngsuite-ancillary/cs5n3p08.html
new file mode 100644
index 0000000000..d1642a1bf5
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cs5n3p08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,89,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,130,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,159,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,183,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,204,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,101,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/cs5n3p08.png b/image/test/reftest/pngsuite-ancillary/cs5n3p08.png
new file mode 100644
index 0000000000..dfd6e6e6ec
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cs5n3p08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/cs8n2c08.html b/image/test/reftest/pngsuite-ancillary/cs8n2c08.html
new file mode 100644
index 0000000000..549341e76c
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cs8n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/cs8n2c08.png b/image/test/reftest/pngsuite-ancillary/cs8n2c08.png
new file mode 100644
index 0000000000..8e01d3294f
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cs8n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/cs8n3p08.html b/image/test/reftest/pngsuite-ancillary/cs8n3p08.html
new file mode 100644
index 0000000000..549341e76c
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cs8n3p08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,98,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,163,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,240,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,224,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/cs8n3p08.png b/image/test/reftest/pngsuite-ancillary/cs8n3p08.png
new file mode 100644
index 0000000000..a44066eb6e
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/cs8n3p08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/ct0n0g04.html b/image/test/reftest/pngsuite-ancillary/ct0n0g04.html
new file mode 100644
index 0000000000..25d3abca33
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ct0n0g04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/ct0n0g04.png b/image/test/reftest/pngsuite-ancillary/ct0n0g04.png
new file mode 100644
index 0000000000..40d1e062f8
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ct0n0g04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/ct1n0g04.html b/image/test/reftest/pngsuite-ancillary/ct1n0g04.html
new file mode 100644
index 0000000000..25d3abca33
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ct1n0g04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/ct1n0g04.png b/image/test/reftest/pngsuite-ancillary/ct1n0g04.png
new file mode 100644
index 0000000000..3ba110aa76
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ct1n0g04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/ctzn0g04.html b/image/test/reftest/pngsuite-ancillary/ctzn0g04.html
new file mode 100644
index 0000000000..25d3abca33
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ctzn0g04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-ancillary/ctzn0g04.png b/image/test/reftest/pngsuite-ancillary/ctzn0g04.png
new file mode 100644
index 0000000000..b4401c9cfc
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/ctzn0g04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-ancillary/qcms-asm-check.js b/image/test/reftest/pngsuite-ancillary/qcms-asm-check.js
new file mode 100644
index 0000000000..32e4434aa7
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/qcms-asm-check.js
@@ -0,0 +1,28 @@
+// This is a workaround for bug 465088, that the qcms assembly doesn't
+// quite match the non-assembly output.
+
+function check_qcms_has_assembly()
+{
+ // We have assembly code on x86 and x86_64 architectures.
+ // Unfortunately, detecting that is a little complicated.
+
+ if (navigator.platform == "MacIntel") {
+ return true;
+ }
+
+ if (navigator.platform.indexOf("Win") == 0 || navigator.platform == "OS/2") {
+ // Assume all Windows and OS/2 is x86 or x86_64. We don't
+ // expose any way for Web content to check.
+ return true;
+ }
+
+ // On most Unix-like platforms, navigator.platform is basically
+ // |uname -sm|.
+ if (navigator.platform.match(/(i[3456]86|x86_64|amd64|i86)/)) {
+ return true;
+ }
+
+ return false;
+}
+
+var qcms_has_assembly = check_qcms_has_assembly();
diff --git a/image/test/reftest/pngsuite-ancillary/reftest.list b/image/test/reftest/pngsuite-ancillary/reftest.list
new file mode 100644
index 0000000000..b5608716cc
--- /dev/null
+++ b/image/test/reftest/pngsuite-ancillary/reftest.list
@@ -0,0 +1,62 @@
+# PngSuite - Ancillary chunks
+
+# cHRM chunks
+#
+# ccwn2c08 - gamma 1.0000 chunk, chroma chunk w:0.3127,0.3290 r:0.64,0.33 g:0.30,0.60 b:0.15,0.06
+fuzzy-if(appleSilicon,1-1,12-12) fuzzy-if(winWidget,0-8,0-569) fuzzy-if(Android,0-1,0-6) == ccwn2c08.png ccwn2c08.html
+# ccwn3p08 - gamma 1.0000 chunk, chroma chunk w:0.3127,0.3290 r:0.64,0.33 g:0.30,0.60 b:0.15,0.06
+fuzzy-if(appleSilicon,1-1,4-4) fuzzy-if(winWidget,0-8,0-577) fuzzy-if(Android,0-1,0-19) == ccwn3p08.png ccwn3p08.html
+
+# pHYs chunks
+#
+# PngSuite implies these first 3 should end up as 32x32 bitmaps, but
+# per discussion in bug 408622 that's not actually true.
+#
+# cdfn2c08 - physical pixel dimensions, 8x32 flat pixels
+== cdfn2c08.png cdfn2c08.html
+# cdhn2c08 - physical pixel dimensions, 32x8 high pixels
+== cdhn2c08.png cdhn2c08.html
+# cdsn2c08 - physical pixel dimensions, 8x8 square pixels
+== cdsn2c08.png cdsn2c08.html
+# cdun2c08 - physical pixel dimensions, 1000 pixels per 1 meter
+== cdun2c08.png cdun2c08.html
+
+# hISt chunks (shouldn't affect display on 24bit systems)
+#
+# ch1n3p04 - histogram 15 colors
+== ch1n3p04.png ch1n3p04.html
+# ch2n3p08 - histogram 256 colors
+== ch2n3p08.png ch2n3p08.html
+
+# tIME chunks (doesn't affect display)
+#
+# cm0n0g04 - modification time, 01-jan-2000 12:34:56
+== cm0n0g04.png cm0n0g04.html
+# cm7n0g04 - modification time, 01-jan-1970 00:00:00
+== cm7n0g04.png cm7n0g04.html
+# cm9n0g04 - modification time, 31-dec-1999 23:59:59
+== cm9n0g04.png cm9n0g04.html
+
+# sBIT chunks
+#
+# cs3n2c16 - color, 13 significant bits
+== cs3n2c16.png cs3n2c16.html
+# cs3n3p08 - paletted, 3 significant bits
+== cs3n3p08.png cs3n3p08.html
+# cs5n2c08 - color, 5 significant bits
+== cs5n2c08.png cs5n2c08.html
+# cs5n3p08 - paletted, 5 significant bits
+== cs5n3p08.png cs5n3p08.html
+# cs8n2c08 - color, 8 significant bits (reference)
+== cs8n2c08.png cs8n2c08.html
+# cs8n3p08 - paletted, 8 significant bits (reference)
+== cs8n3p08.png cs8n3p08.html
+
+# tEXt chunks (doesn't affect display)
+#
+# ct0n0g04 - no textual data
+== ct0n0g04.png ct0n0g04.html
+# ct1n0g04 - with textual data
+== ct1n0g04.png ct1n0g04.html
+# ctzn0g04 - with compressed textual data
+== ctzn0g04.png ctzn0g04.html
diff --git a/image/test/reftest/pngsuite-background/bg__4a08.html b/image/test/reftest/pngsuite-background/bg__4a08.html
new file mode 100644
index 0000000000..743ad1200a
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/bg__4a08.html
@@ -0,0 +1,1092 @@
+<html><body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(18,105,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,110,250,1)'></td>
+ <td width='1' style='background-color: rgba(33,115,250,1)'></td>
+ <td width='1' style='background-color: rgba(41,119,251,1)'></td>
+ <td width='1' style='background-color: rgba(49,125,251,1)'></td>
+ <td width='1' style='background-color: rgba(57,130,251,1)'></td>
+ <td width='1' style='background-color: rgba(65,135,251,1)'></td>
+ <td width='1' style='background-color: rgba(72,140,251,1)'></td>
+ <td width='1' style='background-color: rgba(81,145,251,1)'></td>
+ <td width='1' style='background-color: rgba(89,150,252,1)'></td>
+ <td width='1' style='background-color: rgba(96,155,252,1)'></td>
+ <td width='1' style='background-color: rgba(104,160,252,1)'></td>
+ <td width='1' style='background-color: rgba(112,164,252,1)'></td>
+ <td width='1' style='background-color: rgba(120,170,252,1)'></td>
+ <td width='1' style='background-color: rgba(128,175,252,1)'></td>
+ <td width='1' style='background-color: rgba(136,180,253,1)'></td>
+ <td width='1' style='background-color: rgba(144,184,253,1)'></td>
+ <td width='1' style='background-color: rgba(152,190,253,1)'></td>
+ <td width='1' style='background-color: rgba(160,195,253,1)'></td>
+ <td width='1' style='background-color: rgba(168,200,253,1)'></td>
+ <td width='1' style='background-color: rgba(175,205,253,1)'></td>
+ <td width='1' style='background-color: rgba(183,209,254,1)'></td>
+ <td width='1' style='background-color: rgba(192,215,254,1)'></td>
+ <td width='1' style='background-color: rgba(199,220,254,1)'></td>
+ <td width='1' style='background-color: rgba(207,225,254,1)'></td>
+ <td width='1' style='background-color: rgba(215,229,254,1)'></td>
+ <td width='1' style='background-color: rgba(223,235,254,1)'></td>
+ <td width='1' style='background-color: rgba(231,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,245,255,1)'></td>
+ <td width='1' style='background-color: rgba(246,250,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(17,104,249,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(32,114,249,1)'></td>
+ <td width='1' style='background-color: rgba(40,118,250,1)'></td>
+ <td width='1' style='background-color: rgba(48,124,250,1)'></td>
+ <td width='1' style='background-color: rgba(56,129,250,1)'></td>
+ <td width='1' style='background-color: rgba(64,134,250,1)'></td>
+ <td width='1' style='background-color: rgba(70,138,249,1)'></td>
+ <td width='1' style='background-color: rgba(79,143,249,1)'></td>
+ <td width='1' style='background-color: rgba(87,148,250,1)'></td>
+ <td width='1' style='background-color: rgba(94,153,250,1)'></td>
+ <td width='1' style='background-color: rgba(102,158,250,1)'></td>
+ <td width='1' style='background-color: rgba(110,162,250,1)'></td>
+ <td width='1' style='background-color: rgba(118,168,250,1)'></td>
+ <td width='1' style='background-color: rgba(126,173,250,1)'></td>
+ <td width='1' style='background-color: rgba(133,177,250,1)'></td>
+ <td width='1' style='background-color: rgba(141,181,250,1)'></td>
+ <td width='1' style='background-color: rgba(149,187,250,1)'></td>
+ <td width='1' style='background-color: rgba(157,192,250,1)'></td>
+ <td width='1' style='background-color: rgba(165,197,250,1)'></td>
+ <td width='1' style='background-color: rgba(172,202,250,1)'></td>
+ <td width='1' style='background-color: rgba(180,206,251,1)'></td>
+ <td width='1' style='background-color: rgba(189,212,251,1)'></td>
+ <td width='1' style='background-color: rgba(195,216,250,1)'></td>
+ <td width='1' style='background-color: rgba(203,221,250,1)'></td>
+ <td width='1' style='background-color: rgba(211,225,250,1)'></td>
+ <td width='1' style='background-color: rgba(219,231,250,1)'></td>
+ <td width='1' style='background-color: rgba(227,236,251,1)'></td>
+ <td width='1' style='background-color: rgba(235,241,251,1)'></td>
+ <td width='1' style='background-color: rgba(242,246,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(17,104,249,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(32,114,249,1)'></td>
+ <td width='1' style='background-color: rgba(39,117,249,1)'></td>
+ <td width='1' style='background-color: rgba(47,123,249,1)'></td>
+ <td width='1' style='background-color: rgba(55,128,249,1)'></td>
+ <td width='1' style='background-color: rgba(63,133,249,1)'></td>
+ <td width='1' style='background-color: rgba(69,137,248,1)'></td>
+ <td width='1' style='background-color: rgba(78,142,248,1)'></td>
+ <td width='1' style='background-color: rgba(86,147,249,1)'></td>
+ <td width='1' style='background-color: rgba(93,152,249,1)'></td>
+ <td width='1' style='background-color: rgba(100,156,248,1)'></td>
+ <td width='1' style='background-color: rgba(108,160,248,1)'></td>
+ <td width='1' style='background-color: rgba(116,166,248,1)'></td>
+ <td width='1' style='background-color: rgba(124,171,248,1)'></td>
+ <td width='1' style='background-color: rgba(131,175,248,1)'></td>
+ <td width='1' style='background-color: rgba(139,179,248,1)'></td>
+ <td width='1' style='background-color: rgba(147,185,248,1)'></td>
+ <td width='1' style='background-color: rgba(155,190,248,1)'></td>
+ <td width='1' style='background-color: rgba(162,194,247,1)'></td>
+ <td width='1' style='background-color: rgba(169,199,247,1)'></td>
+ <td width='1' style='background-color: rgba(177,203,248,1)'></td>
+ <td width='1' style='background-color: rgba(186,209,248,1)'></td>
+ <td width='1' style='background-color: rgba(192,213,247,1)'></td>
+ <td width='1' style='background-color: rgba(200,218,247,1)'></td>
+ <td width='1' style='background-color: rgba(208,222,247,1)'></td>
+ <td width='1' style='background-color: rgba(216,228,247,1)'></td>
+ <td width='1' style='background-color: rgba(223,232,247,1)'></td>
+ <td width='1' style='background-color: rgba(231,237,247,1)'></td>
+ <td width='1' style='background-color: rgba(238,242,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(17,104,249,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(31,113,248,1)'></td>
+ <td width='1' style='background-color: rgba(39,117,249,1)'></td>
+ <td width='1' style='background-color: rgba(47,123,249,1)'></td>
+ <td width='1' style='background-color: rgba(54,127,248,1)'></td>
+ <td width='1' style='background-color: rgba(62,132,248,1)'></td>
+ <td width='1' style='background-color: rgba(68,136,247,1)'></td>
+ <td width='1' style='background-color: rgba(77,141,247,1)'></td>
+ <td width='1' style='background-color: rgba(85,146,248,1)'></td>
+ <td width='1' style='background-color: rgba(91,150,247,1)'></td>
+ <td width='1' style='background-color: rgba(99,155,247,1)'></td>
+ <td width='1' style='background-color: rgba(107,159,247,1)'></td>
+ <td width='1' style='background-color: rgba(114,164,246,1)'></td>
+ <td width='1' style='background-color: rgba(122,169,246,1)'></td>
+ <td width='1' style='background-color: rgba(129,173,246,1)'></td>
+ <td width='1' style='background-color: rgba(137,177,246,1)'></td>
+ <td width='1' style='background-color: rgba(145,183,246,1)'></td>
+ <td width='1' style='background-color: rgba(152,187,245,1)'></td>
+ <td width='1' style='background-color: rgba(160,192,245,1)'></td>
+ <td width='1' style='background-color: rgba(166,196,244,1)'></td>
+ <td width='1' style='background-color: rgba(174,200,245,1)'></td>
+ <td width='1' style='background-color: rgba(183,206,245,1)'></td>
+ <td width='1' style='background-color: rgba(189,210,244,1)'></td>
+ <td width='1' style='background-color: rgba(197,215,244,1)'></td>
+ <td width='1' style='background-color: rgba(204,218,243,1)'></td>
+ <td width='1' style='background-color: rgba(212,224,243,1)'></td>
+ <td width='1' style='background-color: rgba(220,229,244,1)'></td>
+ <td width='1' style='background-color: rgba(227,233,243,1)'></td>
+ <td width='1' style='background-color: rgba(234,238,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(17,104,249,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(31,113,248,1)'></td>
+ <td width='1' style='background-color: rgba(38,116,248,1)'></td>
+ <td width='1' style='background-color: rgba(46,122,248,1)'></td>
+ <td width='1' style='background-color: rgba(53,126,247,1)'></td>
+ <td width='1' style='background-color: rgba(61,131,247,1)'></td>
+ <td width='1' style='background-color: rgba(67,135,246,1)'></td>
+ <td width='1' style='background-color: rgba(76,140,246,1)'></td>
+ <td width='1' style='background-color: rgba(83,144,246,1)'></td>
+ <td width='1' style='background-color: rgba(90,149,246,1)'></td>
+ <td width='1' style='background-color: rgba(97,153,245,1)'></td>
+ <td width='1' style='background-color: rgba(105,157,245,1)'></td>
+ <td width='1' style='background-color: rgba(112,162,244,1)'></td>
+ <td width='1' style='background-color: rgba(120,167,244,1)'></td>
+ <td width='1' style='background-color: rgba(127,171,244,1)'></td>
+ <td width='1' style='background-color: rgba(135,175,244,1)'></td>
+ <td width='1' style='background-color: rgba(142,180,243,1)'></td>
+ <td width='1' style='background-color: rgba(150,185,243,1)'></td>
+ <td width='1' style='background-color: rgba(157,189,242,1)'></td>
+ <td width='1' style='background-color: rgba(164,194,242,1)'></td>
+ <td width='1' style='background-color: rgba(171,197,242,1)'></td>
+ <td width='1' style='background-color: rgba(180,203,242,1)'></td>
+ <td width='1' style='background-color: rgba(186,207,241,1)'></td>
+ <td width='1' style='background-color: rgba(194,212,241,1)'></td>
+ <td width='1' style='background-color: rgba(201,215,240,1)'></td>
+ <td width='1' style='background-color: rgba(209,221,240,1)'></td>
+ <td width='1' style='background-color: rgba(216,225,240,1)'></td>
+ <td width='1' style='background-color: rgba(224,230,240,1)'></td>
+ <td width='1' style='background-color: rgba(230,234,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(17,104,249,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(31,113,248,1)'></td>
+ <td width='1' style='background-color: rgba(38,116,248,1)'></td>
+ <td width='1' style='background-color: rgba(45,121,247,1)'></td>
+ <td width='1' style='background-color: rgba(53,126,247,1)'></td>
+ <td width='1' style='background-color: rgba(60,130,246,1)'></td>
+ <td width='1' style='background-color: rgba(66,134,245,1)'></td>
+ <td width='1' style='background-color: rgba(75,139,245,1)'></td>
+ <td width='1' style='background-color: rgba(82,143,245,1)'></td>
+ <td width='1' style='background-color: rgba(88,147,244,1)'></td>
+ <td width='1' style='background-color: rgba(96,152,244,1)'></td>
+ <td width='1' style='background-color: rgba(103,155,243,1)'></td>
+ <td width='1' style='background-color: rgba(110,160,242,1)'></td>
+ <td width='1' style='background-color: rgba(118,165,242,1)'></td>
+ <td width='1' style='background-color: rgba(125,169,242,1)'></td>
+ <td width='1' style='background-color: rgba(133,173,242,1)'></td>
+ <td width='1' style='background-color: rgba(140,178,241,1)'></td>
+ <td width='1' style='background-color: rgba(147,182,240,1)'></td>
+ <td width='1' style='background-color: rgba(155,187,240,1)'></td>
+ <td width='1' style='background-color: rgba(161,191,239,1)'></td>
+ <td width='1' style='background-color: rgba(168,194,239,1)'></td>
+ <td width='1' style='background-color: rgba(177,200,239,1)'></td>
+ <td width='1' style='background-color: rgba(183,204,238,1)'></td>
+ <td width='1' style='background-color: rgba(190,208,237,1)'></td>
+ <td width='1' style='background-color: rgba(198,212,237,1)'></td>
+ <td width='1' style='background-color: rgba(205,217,236,1)'></td>
+ <td width='1' style='background-color: rgba(212,221,236,1)'></td>
+ <td width='1' style='background-color: rgba(220,226,236,1)'></td>
+ <td width='1' style='background-color: rgba(226,230,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(17,104,249,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(30,112,247,1)'></td>
+ <td width='1' style='background-color: rgba(37,115,247,1)'></td>
+ <td width='1' style='background-color: rgba(45,121,247,1)'></td>
+ <td width='1' style='background-color: rgba(52,125,246,1)'></td>
+ <td width='1' style='background-color: rgba(59,129,245,1)'></td>
+ <td width='1' style='background-color: rgba(65,133,244,1)'></td>
+ <td width='1' style='background-color: rgba(74,138,244,1)'></td>
+ <td width='1' style='background-color: rgba(81,142,244,1)'></td>
+ <td width='1' style='background-color: rgba(87,146,243,1)'></td>
+ <td width='1' style='background-color: rgba(94,150,242,1)'></td>
+ <td width='1' style='background-color: rgba(102,154,242,1)'></td>
+ <td width='1' style='background-color: rgba(109,159,241,1)'></td>
+ <td width='1' style='background-color: rgba(116,163,240,1)'></td>
+ <td width='1' style='background-color: rgba(123,167,240,1)'></td>
+ <td width='1' style='background-color: rgba(130,170,239,1)'></td>
+ <td width='1' style='background-color: rgba(138,176,239,1)'></td>
+ <td width='1' style='background-color: rgba(145,180,238,1)'></td>
+ <td width='1' style='background-color: rgba(152,184,237,1)'></td>
+ <td width='1' style='background-color: rgba(158,188,236,1)'></td>
+ <td width='1' style='background-color: rgba(166,192,237,1)'></td>
+ <td width='1' style='background-color: rgba(174,197,236,1)'></td>
+ <td width='1' style='background-color: rgba(180,201,235,1)'></td>
+ <td width='1' style='background-color: rgba(187,205,234,1)'></td>
+ <td width='1' style='background-color: rgba(194,208,233,1)'></td>
+ <td width='1' style='background-color: rgba(202,214,233,1)'></td>
+ <td width='1' style='background-color: rgba(209,218,233,1)'></td>
+ <td width='1' style='background-color: rgba(216,222,232,1)'></td>
+ <td width='1' style='background-color: rgba(222,226,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(17,104,249,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(30,112,247,1)'></td>
+ <td width='1' style='background-color: rgba(37,115,247,1)'></td>
+ <td width='1' style='background-color: rgba(44,120,246,1)'></td>
+ <td width='1' style='background-color: rgba(51,124,245,1)'></td>
+ <td width='1' style='background-color: rgba(58,128,244,1)'></td>
+ <td width='1' style='background-color: rgba(64,132,243,1)'></td>
+ <td width='1' style='background-color: rgba(72,136,242,1)'></td>
+ <td width='1' style='background-color: rgba(79,140,242,1)'></td>
+ <td width='1' style='background-color: rgba(86,145,242,1)'></td>
+ <td width='1' style='background-color: rgba(93,149,241,1)'></td>
+ <td width='1' style='background-color: rgba(100,152,240,1)'></td>
+ <td width='1' style='background-color: rgba(107,157,239,1)'></td>
+ <td width='1' style='background-color: rgba(114,161,238,1)'></td>
+ <td width='1' style='background-color: rgba(121,165,238,1)'></td>
+ <td width='1' style='background-color: rgba(128,168,237,1)'></td>
+ <td width='1' style='background-color: rgba(135,173,236,1)'></td>
+ <td width='1' style='background-color: rgba(142,177,235,1)'></td>
+ <td width='1' style='background-color: rgba(149,181,234,1)'></td>
+ <td width='1' style='background-color: rgba(156,186,234,1)'></td>
+ <td width='1' style='background-color: rgba(163,189,234,1)'></td>
+ <td width='1' style='background-color: rgba(171,194,233,1)'></td>
+ <td width='1' style='background-color: rgba(177,198,232,1)'></td>
+ <td width='1' style='background-color: rgba(184,202,231,1)'></td>
+ <td width='1' style='background-color: rgba(191,205,230,1)'></td>
+ <td width='1' style='background-color: rgba(198,210,229,1)'></td>
+ <td width='1' style='background-color: rgba(205,214,229,1)'></td>
+ <td width='1' style='background-color: rgba(212,218,228,1)'></td>
+ <td width='1' style='background-color: rgba(218,222,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(16,103,248,1)'></td>
+ <td width='1' style='background-color: rgba(22,107,247,1)'></td>
+ <td width='1' style='background-color: rgba(29,111,246,1)'></td>
+ <td width='1' style='background-color: rgba(36,114,246,1)'></td>
+ <td width='1' style='background-color: rgba(43,119,245,1)'></td>
+ <td width='1' style='background-color: rgba(50,123,244,1)'></td>
+ <td width='1' style='background-color: rgba(57,127,243,1)'></td>
+ <td width='1' style='background-color: rgba(63,131,242,1)'></td>
+ <td width='1' style='background-color: rgba(71,135,241,1)'></td>
+ <td width='1' style='background-color: rgba(78,139,241,1)'></td>
+ <td width='1' style='background-color: rgba(84,143,240,1)'></td>
+ <td width='1' style='background-color: rgba(91,147,239,1)'></td>
+ <td width='1' style='background-color: rgba(98,150,238,1)'></td>
+ <td width='1' style='background-color: rgba(105,155,237,1)'></td>
+ <td width='1' style='background-color: rgba(112,159,236,1)'></td>
+ <td width='1' style='background-color: rgba(119,163,236,1)'></td>
+ <td width='1' style='background-color: rgba(126,166,235,1)'></td>
+ <td width='1' style='background-color: rgba(133,171,234,1)'></td>
+ <td width='1' style='background-color: rgba(140,175,233,1)'></td>
+ <td width='1' style='background-color: rgba(147,179,232,1)'></td>
+ <td width='1' style='background-color: rgba(153,183,231,1)'></td>
+ <td width='1' style='background-color: rgba(160,186,231,1)'></td>
+ <td width='1' style='background-color: rgba(168,191,230,1)'></td>
+ <td width='1' style='background-color: rgba(174,195,229,1)'></td>
+ <td width='1' style='background-color: rgba(181,199,228,1)'></td>
+ <td width='1' style='background-color: rgba(188,202,227,1)'></td>
+ <td width='1' style='background-color: rgba(195,207,226,1)'></td>
+ <td width='1' style='background-color: rgba(202,211,226,1)'></td>
+ <td width='1' style='background-color: rgba(209,215,225,1)'></td>
+ <td width='1' style='background-color: rgba(215,219,224,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(16,103,248,1)'></td>
+ <td width='1' style='background-color: rgba(22,107,247,1)'></td>
+ <td width='1' style='background-color: rgba(29,111,246,1)'></td>
+ <td width='1' style='background-color: rgba(36,114,246,1)'></td>
+ <td width='1' style='background-color: rgba(43,119,245,1)'></td>
+ <td width='1' style='background-color: rgba(49,122,243,1)'></td>
+ <td width='1' style='background-color: rgba(56,126,242,1)'></td>
+ <td width='1' style='background-color: rgba(62,130,241,1)'></td>
+ <td width='1' style='background-color: rgba(70,134,240,1)'></td>
+ <td width='1' style='background-color: rgba(77,138,240,1)'></td>
+ <td width='1' style='background-color: rgba(82,141,238,1)'></td>
+ <td width='1' style='background-color: rgba(89,145,237,1)'></td>
+ <td width='1' style='background-color: rgba(96,148,236,1)'></td>
+ <td width='1' style='background-color: rgba(103,153,235,1)'></td>
+ <td width='1' style='background-color: rgba(110,157,234,1)'></td>
+ <td width='1' style='background-color: rgba(116,160,233,1)'></td>
+ <td width='1' style='background-color: rgba(123,163,232,1)'></td>
+ <td width='1' style='background-color: rgba(130,168,231,1)'></td>
+ <td width='1' style='background-color: rgba(137,172,230,1)'></td>
+ <td width='1' style='background-color: rgba(144,176,229,1)'></td>
+ <td width='1' style='background-color: rgba(150,180,228,1)'></td>
+ <td width='1' style='background-color: rgba(156,182,227,1)'></td>
+ <td width='1' style='background-color: rgba(164,187,226,1)'></td>
+ <td width='1' style='background-color: rgba(170,191,225,1)'></td>
+ <td width='1' style='background-color: rgba(177,195,224,1)'></td>
+ <td width='1' style='background-color: rgba(184,198,223,1)'></td>
+ <td width='1' style='background-color: rgba(190,202,221,1)'></td>
+ <td width='1' style='background-color: rgba(197,206,221,1)'></td>
+ <td width='1' style='background-color: rgba(204,210,220,1)'></td>
+ <td width='1' style='background-color: rgba(210,214,219,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(16,103,248,1)'></td>
+ <td width='1' style='background-color: rgba(22,107,247,1)'></td>
+ <td width='1' style='background-color: rgba(29,111,246,1)'></td>
+ <td width='1' style='background-color: rgba(35,113,245,1)'></td>
+ <td width='1' style='background-color: rgba(42,118,244,1)'></td>
+ <td width='1' style='background-color: rgba(48,121,242,1)'></td>
+ <td width='1' style='background-color: rgba(55,125,241,1)'></td>
+ <td width='1' style='background-color: rgba(61,129,240,1)'></td>
+ <td width='1' style='background-color: rgba(68,132,238,1)'></td>
+ <td width='1' style='background-color: rgba(75,136,238,1)'></td>
+ <td width='1' style='background-color: rgba(81,140,237,1)'></td>
+ <td width='1' style='background-color: rgba(87,143,235,1)'></td>
+ <td width='1' style='background-color: rgba(94,146,234,1)'></td>
+ <td width='1' style='background-color: rgba(101,151,233,1)'></td>
+ <td width='1' style='background-color: rgba(107,154,231,1)'></td>
+ <td width='1' style='background-color: rgba(114,158,231,1)'></td>
+ <td width='1' style='background-color: rgba(121,161,230,1)'></td>
+ <td width='1' style='background-color: rgba(127,165,228,1)'></td>
+ <td width='1' style='background-color: rgba(134,169,227,1)'></td>
+ <td width='1' style='background-color: rgba(140,172,225,1)'></td>
+ <td width='1' style='background-color: rgba(146,176,224,1)'></td>
+ <td width='1' style='background-color: rgba(153,179,224,1)'></td>
+ <td width='1' style='background-color: rgba(160,183,222,1)'></td>
+ <td width='1' style='background-color: rgba(166,187,221,1)'></td>
+ <td width='1' style='background-color: rgba(173,191,220,1)'></td>
+ <td width='1' style='background-color: rgba(179,193,218,1)'></td>
+ <td width='1' style='background-color: rgba(186,198,217,1)'></td>
+ <td width='1' style='background-color: rgba(193,202,217,1)'></td>
+ <td width='1' style='background-color: rgba(199,205,215,1)'></td>
+ <td width='1' style='background-color: rgba(205,209,214,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(16,103,248,1)'></td>
+ <td width='1' style='background-color: rgba(22,107,247,1)'></td>
+ <td width='1' style='background-color: rgba(28,110,245,1)'></td>
+ <td width='1' style='background-color: rgba(35,113,245,1)'></td>
+ <td width='1' style='background-color: rgba(41,117,243,1)'></td>
+ <td width='1' style='background-color: rgba(48,121,242,1)'></td>
+ <td width='1' style='background-color: rgba(54,124,240,1)'></td>
+ <td width='1' style='background-color: rgba(60,128,239,1)'></td>
+ <td width='1' style='background-color: rgba(67,131,237,1)'></td>
+ <td width='1' style='background-color: rgba(74,135,237,1)'></td>
+ <td width='1' style='background-color: rgba(79,138,235,1)'></td>
+ <td width='1' style='background-color: rgba(86,142,234,1)'></td>
+ <td width='1' style='background-color: rgba(92,144,232,1)'></td>
+ <td width='1' style='background-color: rgba(99,149,231,1)'></td>
+ <td width='1' style='background-color: rgba(105,152,229,1)'></td>
+ <td width='1' style='background-color: rgba(112,156,229,1)'></td>
+ <td width='1' style='background-color: rgba(118,158,227,1)'></td>
+ <td width='1' style='background-color: rgba(125,163,226,1)'></td>
+ <td width='1' style='background-color: rgba(131,166,224,1)'></td>
+ <td width='1' style='background-color: rgba(138,170,223,1)'></td>
+ <td width='1' style='background-color: rgba(143,173,221,1)'></td>
+ <td width='1' style='background-color: rgba(150,176,221,1)'></td>
+ <td width='1' style='background-color: rgba(157,180,219,1)'></td>
+ <td width='1' style='background-color: rgba(163,184,218,1)'></td>
+ <td width='1' style='background-color: rgba(170,188,217,1)'></td>
+ <td width='1' style='background-color: rgba(176,190,215,1)'></td>
+ <td width='1' style='background-color: rgba(182,194,213,1)'></td>
+ <td width='1' style='background-color: rgba(189,198,213,1)'></td>
+ <td width='1' style='background-color: rgba(196,202,212,1)'></td>
+ <td width='1' style='background-color: rgba(201,205,210,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(16,103,248,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(28,110,245,1)'></td>
+ <td width='1' style='background-color: rgba(34,112,244,1)'></td>
+ <td width='1' style='background-color: rgba(40,116,242,1)'></td>
+ <td width='1' style='background-color: rgba(47,120,241,1)'></td>
+ <td width='1' style='background-color: rgba(53,123,239,1)'></td>
+ <td width='1' style='background-color: rgba(59,127,238,1)'></td>
+ <td width='1' style='background-color: rgba(66,130,236,1)'></td>
+ <td width='1' style='background-color: rgba(72,133,235,1)'></td>
+ <td width='1' style='background-color: rgba(78,137,234,1)'></td>
+ <td width='1' style='background-color: rgba(84,140,232,1)'></td>
+ <td width='1' style='background-color: rgba(90,142,230,1)'></td>
+ <td width='1' style='background-color: rgba(97,147,229,1)'></td>
+ <td width='1' style='background-color: rgba(103,150,227,1)'></td>
+ <td width='1' style='background-color: rgba(109,153,226,1)'></td>
+ <td width='1' style='background-color: rgba(116,156,225,1)'></td>
+ <td width='1' style='background-color: rgba(122,160,223,1)'></td>
+ <td width='1' style='background-color: rgba(128,163,221,1)'></td>
+ <td width='1' style='background-color: rgba(135,167,220,1)'></td>
+ <td width='1' style='background-color: rgba(140,170,218,1)'></td>
+ <td width='1' style='background-color: rgba(147,173,218,1)'></td>
+ <td width='1' style='background-color: rgba(154,177,216,1)'></td>
+ <td width='1' style='background-color: rgba(159,180,214,1)'></td>
+ <td width='1' style='background-color: rgba(166,184,213,1)'></td>
+ <td width='1' style='background-color: rgba(172,186,211,1)'></td>
+ <td width='1' style='background-color: rgba(178,190,209,1)'></td>
+ <td width='1' style='background-color: rgba(185,194,209,1)'></td>
+ <td width='1' style='background-color: rgba(191,197,207,1)'></td>
+ <td width='1' style='background-color: rgba(196,200,205,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(16,103,248,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(27,109,244,1)'></td>
+ <td width='1' style='background-color: rgba(33,111,243,1)'></td>
+ <td width='1' style='background-color: rgba(39,115,241,1)'></td>
+ <td width='1' style='background-color: rgba(46,119,240,1)'></td>
+ <td width='1' style='background-color: rgba(52,122,238,1)'></td>
+ <td width='1' style='background-color: rgba(57,125,236,1)'></td>
+ <td width='1' style='background-color: rgba(64,128,234,1)'></td>
+ <td width='1' style='background-color: rgba(70,131,233,1)'></td>
+ <td width='1' style='background-color: rgba(76,135,232,1)'></td>
+ <td width='1' style='background-color: rgba(82,138,230,1)'></td>
+ <td width='1' style='background-color: rgba(88,140,228,1)'></td>
+ <td width='1' style='background-color: rgba(94,144,226,1)'></td>
+ <td width='1' style='background-color: rgba(100,147,224,1)'></td>
+ <td width='1' style='background-color: rgba(107,151,224,1)'></td>
+ <td width='1' style='background-color: rgba(113,153,222,1)'></td>
+ <td width='1' style='background-color: rgba(119,157,220,1)'></td>
+ <td width='1' style='background-color: rgba(125,160,218,1)'></td>
+ <td width='1' style='background-color: rgba(131,163,216,1)'></td>
+ <td width='1' style='background-color: rgba(137,167,215,1)'></td>
+ <td width='1' style='background-color: rgba(143,169,214,1)'></td>
+ <td width='1' style='background-color: rgba(150,173,212,1)'></td>
+ <td width='1' style='background-color: rgba(155,176,210,1)'></td>
+ <td width='1' style='background-color: rgba(161,179,208,1)'></td>
+ <td width='1' style='background-color: rgba(168,182,207,1)'></td>
+ <td width='1' style='background-color: rgba(174,186,205,1)'></td>
+ <td width='1' style='background-color: rgba(180,189,204,1)'></td>
+ <td width='1' style='background-color: rgba(186,192,202,1)'></td>
+ <td width='1' style='background-color: rgba(191,195,200,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(16,103,248,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(27,109,244,1)'></td>
+ <td width='1' style='background-color: rgba(33,111,243,1)'></td>
+ <td width='1' style='background-color: rgba(39,115,241,1)'></td>
+ <td width='1' style='background-color: rgba(45,118,239,1)'></td>
+ <td width='1' style='background-color: rgba(51,121,237,1)'></td>
+ <td width='1' style='background-color: rgba(56,124,235,1)'></td>
+ <td width='1' style='background-color: rgba(63,127,233,1)'></td>
+ <td width='1' style='background-color: rgba(69,130,232,1)'></td>
+ <td width='1' style='background-color: rgba(74,133,230,1)'></td>
+ <td width='1' style='background-color: rgba(80,136,228,1)'></td>
+ <td width='1' style='background-color: rgba(86,138,226,1)'></td>
+ <td width='1' style='background-color: rgba(92,142,224,1)'></td>
+ <td width='1' style='background-color: rgba(98,145,222,1)'></td>
+ <td width='1' style='background-color: rgba(104,148,221,1)'></td>
+ <td width='1' style='background-color: rgba(110,150,219,1)'></td>
+ <td width='1' style='background-color: rgba(116,154,217,1)'></td>
+ <td width='1' style='background-color: rgba(122,157,215,1)'></td>
+ <td width='1' style='background-color: rgba(128,160,213,1)'></td>
+ <td width='1' style='background-color: rgba(133,163,211,1)'></td>
+ <td width='1' style='background-color: rgba(139,165,210,1)'></td>
+ <td width='1' style='background-color: rgba(146,169,208,1)'></td>
+ <td width='1' style='background-color: rgba(151,172,206,1)'></td>
+ <td width='1' style='background-color: rgba(157,175,204,1)'></td>
+ <td width='1' style='background-color: rgba(164,178,203,1)'></td>
+ <td width='1' style='background-color: rgba(169,181,200,1)'></td>
+ <td width='1' style='background-color: rgba(175,184,199,1)'></td>
+ <td width='1' style='background-color: rgba(182,188,198,1)'></td>
+ <td width='1' style='background-color: rgba(187,191,196,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(15,102,247,1)'></td>
+ <td width='1' style='background-color: rgba(20,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(26,108,243,1)'></td>
+ <td width='1' style='background-color: rgba(32,110,242,1)'></td>
+ <td width='1' style='background-color: rgba(38,114,240,1)'></td>
+ <td width='1' style='background-color: rgba(44,117,238,1)'></td>
+ <td width='1' style='background-color: rgba(50,120,236,1)'></td>
+ <td width='1' style='background-color: rgba(54,122,233,1)'></td>
+ <td width='1' style='background-color: rgba(61,125,231,1)'></td>
+ <td width='1' style='background-color: rgba(67,128,230,1)'></td>
+ <td width='1' style='background-color: rgba(72,131,228,1)'></td>
+ <td width='1' style='background-color: rgba(78,134,226,1)'></td>
+ <td width='1' style='background-color: rgba(84,136,224,1)'></td>
+ <td width='1' style='background-color: rgba(89,139,221,1)'></td>
+ <td width='1' style='background-color: rgba(95,142,219,1)'></td>
+ <td width='1' style='background-color: rgba(101,145,218,1)'></td>
+ <td width='1' style='background-color: rgba(107,147,216,1)'></td>
+ <td width='1' style='background-color: rgba(113,151,214,1)'></td>
+ <td width='1' style='background-color: rgba(119,154,212,1)'></td>
+ <td width='1' style='background-color: rgba(124,156,209,1)'></td>
+ <td width='1' style='background-color: rgba(129,159,207,1)'></td>
+ <td width='1' style='background-color: rgba(135,161,206,1)'></td>
+ <td width='1' style='background-color: rgba(142,165,204,1)'></td>
+ <td width='1' style='background-color: rgba(147,168,202,1)'></td>
+ <td width='1' style='background-color: rgba(153,171,200,1)'></td>
+ <td width='1' style='background-color: rgba(159,173,198,1)'></td>
+ <td width='1' style='background-color: rgba(164,176,195,1)'></td>
+ <td width='1' style='background-color: rgba(170,179,194,1)'></td>
+ <td width='1' style='background-color: rgba(176,182,192,1)'></td>
+ <td width='1' style='background-color: rgba(181,185,190,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(15,102,247,1)'></td>
+ <td width='1' style='background-color: rgba(20,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(26,108,243,1)'></td>
+ <td width='1' style='background-color: rgba(31,109,241,1)'></td>
+ <td width='1' style='background-color: rgba(37,113,239,1)'></td>
+ <td width='1' style='background-color: rgba(43,116,237,1)'></td>
+ <td width='1' style='background-color: rgba(48,118,234,1)'></td>
+ <td width='1' style='background-color: rgba(53,121,232,1)'></td>
+ <td width='1' style='background-color: rgba(60,124,230,1)'></td>
+ <td width='1' style='background-color: rgba(65,126,228,1)'></td>
+ <td width='1' style='background-color: rgba(70,129,226,1)'></td>
+ <td width='1' style='background-color: rgba(76,132,224,1)'></td>
+ <td width='1' style='background-color: rgba(82,134,222,1)'></td>
+ <td width='1' style='background-color: rgba(87,137,219,1)'></td>
+ <td width='1' style='background-color: rgba(93,140,217,1)'></td>
+ <td width='1' style='background-color: rgba(99,143,216,1)'></td>
+ <td width='1' style='background-color: rgba(104,144,213,1)'></td>
+ <td width='1' style='background-color: rgba(110,148,211,1)'></td>
+ <td width='1' style='background-color: rgba(115,150,208,1)'></td>
+ <td width='1' style='background-color: rgba(121,153,206,1)'></td>
+ <td width='1' style='background-color: rgba(126,156,204,1)'></td>
+ <td width='1' style='background-color: rgba(132,158,203,1)'></td>
+ <td width='1' style='background-color: rgba(138,161,200,1)'></td>
+ <td width='1' style='background-color: rgba(143,164,198,1)'></td>
+ <td width='1' style='background-color: rgba(149,167,196,1)'></td>
+ <td width='1' style='background-color: rgba(154,168,193,1)'></td>
+ <td width='1' style='background-color: rgba(160,172,191,1)'></td>
+ <td width='1' style='background-color: rgba(166,175,190,1)'></td>
+ <td width='1' style='background-color: rgba(171,177,187,1)'></td>
+ <td width='1' style='background-color: rgba(176,180,185,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(15,102,247,1)'></td>
+ <td width='1' style='background-color: rgba(20,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(25,107,242,1)'></td>
+ <td width='1' style='background-color: rgba(31,109,241,1)'></td>
+ <td width='1' style='background-color: rgba(36,112,238,1)'></td>
+ <td width='1' style='background-color: rgba(42,115,236,1)'></td>
+ <td width='1' style='background-color: rgba(47,117,233,1)'></td>
+ <td width='1' style='background-color: rgba(52,120,231,1)'></td>
+ <td width='1' style='background-color: rgba(58,122,228,1)'></td>
+ <td width='1' style='background-color: rgba(64,125,227,1)'></td>
+ <td width='1' style='background-color: rgba(68,127,224,1)'></td>
+ <td width='1' style='background-color: rgba(74,130,222,1)'></td>
+ <td width='1' style='background-color: rgba(79,131,219,1)'></td>
+ <td width='1' style='background-color: rgba(85,135,217,1)'></td>
+ <td width='1' style='background-color: rgba(90,137,214,1)'></td>
+ <td width='1' style='background-color: rgba(96,140,213,1)'></td>
+ <td width='1' style='background-color: rgba(102,142,211,1)'></td>
+ <td width='1' style='background-color: rgba(107,145,208,1)'></td>
+ <td width='1' style='background-color: rgba(112,147,205,1)'></td>
+ <td width='1' style='background-color: rgba(118,150,203,1)'></td>
+ <td width='1' style='background-color: rgba(123,153,201,1)'></td>
+ <td width='1' style='background-color: rgba(128,154,199,1)'></td>
+ <td width='1' style='background-color: rgba(134,157,196,1)'></td>
+ <td width='1' style='background-color: rgba(139,160,194,1)'></td>
+ <td width='1' style='background-color: rgba(145,163,192,1)'></td>
+ <td width='1' style='background-color: rgba(150,164,189,1)'></td>
+ <td width='1' style='background-color: rgba(155,167,186,1)'></td>
+ <td width='1' style='background-color: rgba(161,170,185,1)'></td>
+ <td width='1' style='background-color: rgba(167,173,183,1)'></td>
+ <td width='1' style='background-color: rgba(171,175,180,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(15,102,247,1)'></td>
+ <td width='1' style='background-color: rgba(19,104,244,1)'></td>
+ <td width='1' style='background-color: rgba(25,107,242,1)'></td>
+ <td width='1' style='background-color: rgba(30,108,240,1)'></td>
+ <td width='1' style='background-color: rgba(35,111,237,1)'></td>
+ <td width='1' style='background-color: rgba(40,113,234,1)'></td>
+ <td width='1' style='background-color: rgba(46,116,232,1)'></td>
+ <td width='1' style='background-color: rgba(50,118,229,1)'></td>
+ <td width='1' style='background-color: rgba(56,120,226,1)'></td>
+ <td width='1' style='background-color: rgba(61,122,224,1)'></td>
+ <td width='1' style='background-color: rgba(66,125,222,1)'></td>
+ <td width='1' style='background-color: rgba(71,127,219,1)'></td>
+ <td width='1' style='background-color: rgba(77,129,217,1)'></td>
+ <td width='1' style='background-color: rgba(82,132,214,1)'></td>
+ <td width='1' style='background-color: rgba(87,134,211,1)'></td>
+ <td width='1' style='background-color: rgba(92,136,209,1)'></td>
+ <td width='1' style='background-color: rgba(98,138,207,1)'></td>
+ <td width='1' style='background-color: rgba(103,141,204,1)'></td>
+ <td width='1' style='background-color: rgba(108,143,201,1)'></td>
+ <td width='1' style='background-color: rgba(113,145,198,1)'></td>
+ <td width='1' style='background-color: rgba(118,148,196,1)'></td>
+ <td width='1' style='background-color: rgba(123,149,194,1)'></td>
+ <td width='1' style='background-color: rgba(129,152,191,1)'></td>
+ <td width='1' style='background-color: rgba(134,155,189,1)'></td>
+ <td width='1' style='background-color: rgba(139,157,186,1)'></td>
+ <td width='1' style='background-color: rgba(144,158,183,1)'></td>
+ <td width='1' style='background-color: rgba(149,161,180,1)'></td>
+ <td width='1' style='background-color: rgba(155,164,179,1)'></td>
+ <td width='1' style='background-color: rgba(160,166,176,1)'></td>
+ <td width='1' style='background-color: rgba(164,168,173,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(15,102,247,1)'></td>
+ <td width='1' style='background-color: rgba(19,104,244,1)'></td>
+ <td width='1' style='background-color: rgba(24,106,241,1)'></td>
+ <td width='1' style='background-color: rgba(29,107,239,1)'></td>
+ <td width='1' style='background-color: rgba(34,110,236,1)'></td>
+ <td width='1' style='background-color: rgba(39,112,233,1)'></td>
+ <td width='1' style='background-color: rgba(44,114,230,1)'></td>
+ <td width='1' style='background-color: rgba(49,117,228,1)'></td>
+ <td width='1' style='background-color: rgba(54,118,224,1)'></td>
+ <td width='1' style='background-color: rgba(60,121,223,1)'></td>
+ <td width='1' style='background-color: rgba(64,123,220,1)'></td>
+ <td width='1' style='background-color: rgba(69,125,217,1)'></td>
+ <td width='1' style='background-color: rgba(74,126,214,1)'></td>
+ <td width='1' style='background-color: rgba(79,129,211,1)'></td>
+ <td width='1' style='background-color: rgba(84,131,208,1)'></td>
+ <td width='1' style='background-color: rgba(89,133,206,1)'></td>
+ <td width='1' style='background-color: rgba(94,134,203,1)'></td>
+ <td width='1' style='background-color: rgba(99,137,200,1)'></td>
+ <td width='1' style='background-color: rgba(104,139,197,1)'></td>
+ <td width='1' style='background-color: rgba(110,142,195,1)'></td>
+ <td width='1' style='background-color: rgba(114,144,192,1)'></td>
+ <td width='1' style='background-color: rgba(119,145,190,1)'></td>
+ <td width='1' style='background-color: rgba(125,148,187,1)'></td>
+ <td width='1' style='background-color: rgba(129,150,184,1)'></td>
+ <td width='1' style='background-color: rgba(134,152,181,1)'></td>
+ <td width='1' style='background-color: rgba(139,153,178,1)'></td>
+ <td width='1' style='background-color: rgba(144,156,175,1)'></td>
+ <td width='1' style='background-color: rgba(149,158,173,1)'></td>
+ <td width='1' style='background-color: rgba(155,161,171,1)'></td>
+ <td width='1' style='background-color: rgba(159,163,168,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(14,101,246,1)'></td>
+ <td width='1' style='background-color: rgba(18,103,243,1)'></td>
+ <td width='1' style='background-color: rgba(23,105,240,1)'></td>
+ <td width='1' style='background-color: rgba(28,106,238,1)'></td>
+ <td width='1' style='background-color: rgba(33,109,235,1)'></td>
+ <td width='1' style='background-color: rgba(38,111,232,1)'></td>
+ <td width='1' style='background-color: rgba(43,113,229,1)'></td>
+ <td width='1' style='background-color: rgba(47,115,226,1)'></td>
+ <td width='1' style='background-color: rgba(53,117,223,1)'></td>
+ <td width='1' style='background-color: rgba(58,119,221,1)'></td>
+ <td width='1' style='background-color: rgba(62,121,218,1)'></td>
+ <td width='1' style='background-color: rgba(67,123,215,1)'></td>
+ <td width='1' style='background-color: rgba(72,124,212,1)'></td>
+ <td width='1' style='background-color: rgba(76,126,208,1)'></td>
+ <td width='1' style='background-color: rgba(81,128,205,1)'></td>
+ <td width='1' style='background-color: rgba(86,130,203,1)'></td>
+ <td width='1' style='background-color: rgba(91,131,200,1)'></td>
+ <td width='1' style='background-color: rgba(96,134,197,1)'></td>
+ <td width='1' style='background-color: rgba(101,136,194,1)'></td>
+ <td width='1' style='background-color: rgba(106,138,191,1)'></td>
+ <td width='1' style='background-color: rgba(110,140,188,1)'></td>
+ <td width='1' style='background-color: rgba(115,141,186,1)'></td>
+ <td width='1' style='background-color: rgba(120,143,182,1)'></td>
+ <td width='1' style='background-color: rgba(124,145,179,1)'></td>
+ <td width='1' style='background-color: rgba(129,147,176,1)'></td>
+ <td width='1' style='background-color: rgba(134,148,173,1)'></td>
+ <td width='1' style='background-color: rgba(139,151,170,1)'></td>
+ <td width='1' style='background-color: rgba(144,153,168,1)'></td>
+ <td width='1' style='background-color: rgba(149,155,165,1)'></td>
+ <td width='1' style='background-color: rgba(153,157,162,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(14,101,246,1)'></td>
+ <td width='1' style='background-color: rgba(18,103,243,1)'></td>
+ <td width='1' style='background-color: rgba(23,105,240,1)'></td>
+ <td width='1' style='background-color: rgba(28,106,238,1)'></td>
+ <td width='1' style='background-color: rgba(32,108,234,1)'></td>
+ <td width='1' style='background-color: rgba(37,110,231,1)'></td>
+ <td width='1' style='background-color: rgba(41,111,227,1)'></td>
+ <td width='1' style='background-color: rgba(45,113,224,1)'></td>
+ <td width='1' style='background-color: rgba(51,115,221,1)'></td>
+ <td width='1' style='background-color: rgba(55,116,218,1)'></td>
+ <td width='1' style='background-color: rgba(59,118,215,1)'></td>
+ <td width='1' style='background-color: rgba(64,120,212,1)'></td>
+ <td width='1' style='background-color: rgba(69,121,209,1)'></td>
+ <td width='1' style='background-color: rgba(73,123,205,1)'></td>
+ <td width='1' style='background-color: rgba(78,125,202,1)'></td>
+ <td width='1' style='background-color: rgba(83,127,200,1)'></td>
+ <td width='1' style='background-color: rgba(87,127,196,1)'></td>
+ <td width='1' style='background-color: rgba(92,130,193,1)'></td>
+ <td width='1' style='background-color: rgba(96,131,189,1)'></td>
+ <td width='1' style='background-color: rgba(101,133,186,1)'></td>
+ <td width='1' style='background-color: rgba(105,135,183,1)'></td>
+ <td width='1' style='background-color: rgba(110,136,181,1)'></td>
+ <td width='1' style='background-color: rgba(115,138,177,1)'></td>
+ <td width='1' style='background-color: rgba(119,140,174,1)'></td>
+ <td width='1' style='background-color: rgba(124,142,171,1)'></td>
+ <td width='1' style='background-color: rgba(128,142,167,1)'></td>
+ <td width='1' style='background-color: rgba(133,145,164,1)'></td>
+ <td width='1' style='background-color: rgba(138,147,162,1)'></td>
+ <td width='1' style='background-color: rgba(142,148,158,1)'></td>
+ <td width='1' style='background-color: rgba(146,150,155,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(14,101,246,1)'></td>
+ <td width='1' style='background-color: rgba(18,103,243,1)'></td>
+ <td width='1' style='background-color: rgba(22,104,239,1)'></td>
+ <td width='1' style='background-color: rgba(27,105,237,1)'></td>
+ <td width='1' style='background-color: rgba(31,107,233,1)'></td>
+ <td width='1' style='background-color: rgba(35,108,229,1)'></td>
+ <td width='1' style='background-color: rgba(40,110,226,1)'></td>
+ <td width='1' style='background-color: rgba(43,111,222,1)'></td>
+ <td width='1' style='background-color: rgba(49,113,219,1)'></td>
+ <td width='1' style='background-color: rgba(53,114,216,1)'></td>
+ <td width='1' style='background-color: rgba(57,116,213,1)'></td>
+ <td width='1' style='background-color: rgba(61,117,209,1)'></td>
+ <td width='1' style='background-color: rgba(66,118,206,1)'></td>
+ <td width='1' style='background-color: rgba(70,120,202,1)'></td>
+ <td width='1' style='background-color: rgba(74,121,198,1)'></td>
+ <td width='1' style='background-color: rgba(79,123,196,1)'></td>
+ <td width='1' style='background-color: rgba(84,124,193,1)'></td>
+ <td width='1' style='background-color: rgba(88,126,189,1)'></td>
+ <td width='1' style='background-color: rgba(92,127,185,1)'></td>
+ <td width='1' style='background-color: rgba(97,129,182,1)'></td>
+ <td width='1' style='background-color: rgba(100,130,178,1)'></td>
+ <td width='1' style='background-color: rgba(105,131,176,1)'></td>
+ <td width='1' style='background-color: rgba(110,133,172,1)'></td>
+ <td width='1' style='background-color: rgba(114,135,169,1)'></td>
+ <td width='1' style='background-color: rgba(118,136,165,1)'></td>
+ <td width='1' style='background-color: rgba(123,137,162,1)'></td>
+ <td width='1' style='background-color: rgba(127,139,158,1)'></td>
+ <td width='1' style='background-color: rgba(131,140,155,1)'></td>
+ <td width='1' style='background-color: rgba(136,142,152,1)'></td>
+ <td width='1' style='background-color: rgba(139,143,148,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(14,101,246,1)'></td>
+ <td width='1' style='background-color: rgba(17,102,242,1)'></td>
+ <td width='1' style='background-color: rgba(21,103,238,1)'></td>
+ <td width='1' style='background-color: rgba(26,104,236,1)'></td>
+ <td width='1' style='background-color: rgba(30,106,232,1)'></td>
+ <td width='1' style='background-color: rgba(34,107,228,1)'></td>
+ <td width='1' style='background-color: rgba(38,108,224,1)'></td>
+ <td width='1' style='background-color: rgba(41,109,220,1)'></td>
+ <td width='1' style='background-color: rgba(46,110,216,1)'></td>
+ <td width='1' style='background-color: rgba(51,112,214,1)'></td>
+ <td width='1' style='background-color: rgba(54,113,210,1)'></td>
+ <td width='1' style='background-color: rgba(58,114,206,1)'></td>
+ <td width='1' style='background-color: rgba(62,114,202,1)'></td>
+ <td width='1' style='background-color: rgba(66,116,198,1)'></td>
+ <td width='1' style='background-color: rgba(71,118,195,1)'></td>
+ <td width='1' style='background-color: rgba(75,119,192,1)'></td>
+ <td width='1' style='background-color: rgba(79,119,188,1)'></td>
+ <td width='1' style='background-color: rgba(83,121,184,1)'></td>
+ <td width='1' style='background-color: rgba(87,122,180,1)'></td>
+ <td width='1' style='background-color: rgba(92,124,177,1)'></td>
+ <td width='1' style='background-color: rgba(95,125,173,1)'></td>
+ <td width='1' style='background-color: rgba(99,125,170,1)'></td>
+ <td width='1' style='background-color: rgba(104,127,166,1)'></td>
+ <td width='1' style='background-color: rgba(107,128,162,1)'></td>
+ <td width='1' style='background-color: rgba(112,130,159,1)'></td>
+ <td width='1' style='background-color: rgba(116,130,155,1)'></td>
+ <td width='1' style='background-color: rgba(120,132,151,1)'></td>
+ <td width='1' style='background-color: rgba(124,133,148,1)'></td>
+ <td width='1' style='background-color: rgba(128,134,144,1)'></td>
+ <td width='1' style='background-color: rgba(132,136,141,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(14,101,246,1)'></td>
+ <td width='1' style='background-color: rgba(17,102,242,1)'></td>
+ <td width='1' style='background-color: rgba(21,103,238,1)'></td>
+ <td width='1' style='background-color: rgba(25,103,235,1)'></td>
+ <td width='1' style='background-color: rgba(28,104,230,1)'></td>
+ <td width='1' style='background-color: rgba(32,105,226,1)'></td>
+ <td width='1' style='background-color: rgba(36,106,222,1)'></td>
+ <td width='1' style='background-color: rgba(39,107,218,1)'></td>
+ <td width='1' style='background-color: rgba(44,108,214,1)'></td>
+ <td width='1' style='background-color: rgba(48,109,211,1)'></td>
+ <td width='1' style='background-color: rgba(51,110,207,1)'></td>
+ <td width='1' style='background-color: rgba(55,111,203,1)'></td>
+ <td width='1' style='background-color: rgba(59,111,199,1)'></td>
+ <td width='1' style='background-color: rgba(63,113,195,1)'></td>
+ <td width='1' style='background-color: rgba(67,114,191,1)'></td>
+ <td width='1' style='background-color: rgba(71,115,188,1)'></td>
+ <td width='1' style='background-color: rgba(75,115,184,1)'></td>
+ <td width='1' style='background-color: rgba(78,116,179,1)'></td>
+ <td width='1' style='background-color: rgba(82,117,175,1)'></td>
+ <td width='1' style='background-color: rgba(86,118,171,1)'></td>
+ <td width='1' style='background-color: rgba(90,120,168,1)'></td>
+ <td width='1' style='background-color: rgba(94,120,165,1)'></td>
+ <td width='1' style='background-color: rgba(98,121,160,1)'></td>
+ <td width='1' style='background-color: rgba(101,122,156,1)'></td>
+ <td width='1' style='background-color: rgba(105,123,152,1)'></td>
+ <td width='1' style='background-color: rgba(109,123,148,1)'></td>
+ <td width='1' style='background-color: rgba(113,125,144,1)'></td>
+ <td width='1' style='background-color: rgba(117,126,141,1)'></td>
+ <td width='1' style='background-color: rgba(121,127,137,1)'></td>
+ <td width='1' style='background-color: rgba(124,128,133,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(13,100,245,1)'></td>
+ <td width='1' style='background-color: rgba(16,101,241,1)'></td>
+ <td width='1' style='background-color: rgba(20,102,237,1)'></td>
+ <td width='1' style='background-color: rgba(24,102,234,1)'></td>
+ <td width='1' style='background-color: rgba(27,103,229,1)'></td>
+ <td width='1' style='background-color: rgba(31,104,225,1)'></td>
+ <td width='1' style='background-color: rgba(34,104,220,1)'></td>
+ <td width='1' style='background-color: rgba(37,105,216,1)'></td>
+ <td width='1' style='background-color: rgba(41,105,211,1)'></td>
+ <td width='1' style='background-color: rgba(45,106,208,1)'></td>
+ <td width='1' style='background-color: rgba(48,107,204,1)'></td>
+ <td width='1' style='background-color: rgba(52,108,200,1)'></td>
+ <td width='1' style='background-color: rgba(55,107,195,1)'></td>
+ <td width='1' style='background-color: rgba(59,109,191,1)'></td>
+ <td width='1' style='background-color: rgba(62,109,186,1)'></td>
+ <td width='1' style='background-color: rgba(66,110,183,1)'></td>
+ <td width='1' style='background-color: rgba(70,110,179,1)'></td>
+ <td width='1' style='background-color: rgba(73,111,174,1)'></td>
+ <td width='1' style='background-color: rgba(77,112,170,1)'></td>
+ <td width='1' style='background-color: rgba(81,113,166,1)'></td>
+ <td width='1' style='background-color: rgba(83,113,161,1)'></td>
+ <td width='1' style='background-color: rgba(87,113,158,1)'></td>
+ <td width='1' style='background-color: rgba(91,114,153,1)'></td>
+ <td width='1' style='background-color: rgba(94,115,149,1)'></td>
+ <td width='1' style='background-color: rgba(98,116,145,1)'></td>
+ <td width='1' style='background-color: rgba(102,116,141,1)'></td>
+ <td width='1' style='background-color: rgba(105,117,136,1)'></td>
+ <td width='1' style='background-color: rgba(109,118,133,1)'></td>
+ <td width='1' style='background-color: rgba(113,119,129,1)'></td>
+ <td width='1' style='background-color: rgba(115,119,124,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(13,100,245,1)'></td>
+ <td width='1' style='background-color: rgba(15,100,240,1)'></td>
+ <td width='1' style='background-color: rgba(19,101,236,1)'></td>
+ <td width='1' style='background-color: rgba(22,100,232,1)'></td>
+ <td width='1' style='background-color: rgba(25,101,227,1)'></td>
+ <td width='1' style='background-color: rgba(29,102,223,1)'></td>
+ <td width='1' style='background-color: rgba(32,102,218,1)'></td>
+ <td width='1' style='background-color: rgba(35,103,214,1)'></td>
+ <td width='1' style='background-color: rgba(39,103,209,1)'></td>
+ <td width='1' style='background-color: rgba(42,103,205,1)'></td>
+ <td width='1' style='background-color: rgba(45,104,201,1)'></td>
+ <td width='1' style='background-color: rgba(48,104,196,1)'></td>
+ <td width='1' style='background-color: rgba(52,104,192,1)'></td>
+ <td width='1' style='background-color: rgba(55,105,187,1)'></td>
+ <td width='1' style='background-color: rgba(58,105,182,1)'></td>
+ <td width='1' style='background-color: rgba(62,106,179,1)'></td>
+ <td width='1' style='background-color: rgba(65,105,174,1)'></td>
+ <td width='1' style='background-color: rgba(68,106,169,1)'></td>
+ <td width='1' style='background-color: rgba(71,106,164,1)'></td>
+ <td width='1' style='background-color: rgba(75,107,160,1)'></td>
+ <td width='1' style='background-color: rgba(77,107,155,1)'></td>
+ <td width='1' style='background-color: rgba(81,107,152,1)'></td>
+ <td width='1' style='background-color: rgba(85,108,147,1)'></td>
+ <td width='1' style='background-color: rgba(87,108,142,1)'></td>
+ <td width='1' style='background-color: rgba(91,109,138,1)'></td>
+ <td width='1' style='background-color: rgba(94,108,133,1)'></td>
+ <td width='1' style='background-color: rgba(97,109,128,1)'></td>
+ <td width='1' style='background-color: rgba(101,110,125,1)'></td>
+ <td width='1' style='background-color: rgba(104,110,120,1)'></td>
+ <td width='1' style='background-color: rgba(107,111,116,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(13,100,245,1)'></td>
+ <td width='1' style='background-color: rgba(15,100,240,1)'></td>
+ <td width='1' style='background-color: rgba(18,100,235,1)'></td>
+ <td width='1' style='background-color: rgba(21,99,231,1)'></td>
+ <td width='1' style='background-color: rgba(23,99,225,1)'></td>
+ <td width='1' style='background-color: rgba(27,100,221,1)'></td>
+ <td width='1' style='background-color: rgba(30,100,216,1)'></td>
+ <td width='1' style='background-color: rgba(32,100,211,1)'></td>
+ <td width='1' style='background-color: rgba(35,99,205,1)'></td>
+ <td width='1' style='background-color: rgba(38,99,201,1)'></td>
+ <td width='1' style='background-color: rgba(40,99,196,1)'></td>
+ <td width='1' style='background-color: rgba(44,100,192,1)'></td>
+ <td width='1' style='background-color: rgba(47,99,187,1)'></td>
+ <td width='1' style='background-color: rgba(49,99,181,1)'></td>
+ <td width='1' style='background-color: rgba(52,99,176,1)'></td>
+ <td width='1' style='background-color: rgba(55,99,172,1)'></td>
+ <td width='1' style='background-color: rgba(58,98,167,1)'></td>
+ <td width='1' style='background-color: rgba(61,99,162,1)'></td>
+ <td width='1' style='background-color: rgba(64,99,157,1)'></td>
+ <td width='1' style='background-color: rgba(67,99,152,1)'></td>
+ <td width='1' style='background-color: rgba(69,99,147,1)'></td>
+ <td width='1' style='background-color: rgba(72,98,143,1)'></td>
+ <td width='1' style='background-color: rgba(76,99,138,1)'></td>
+ <td width='1' style='background-color: rgba(78,99,133,1)'></td>
+ <td width='1' style='background-color: rgba(81,99,128,1)'></td>
+ <td width='1' style='background-color: rgba(84,98,123,1)'></td>
+ <td width='1' style='background-color: rgba(87,99,118,1)'></td>
+ <td width='1' style='background-color: rgba(90,99,114,1)'></td>
+ <td width='1' style='background-color: rgba(93,99,109,1)'></td>
+ <td width='1' style='background-color: rgba(95,99,104,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(12,99,244,1)'></td>
+ <td width='1' style='background-color: rgba(14,99,239,1)'></td>
+ <td width='1' style='background-color: rgba(17,99,234,1)'></td>
+ <td width='1' style='background-color: rgba(19,97,229,1)'></td>
+ <td width='1' style='background-color: rgba(21,97,223,1)'></td>
+ <td width='1' style='background-color: rgba(24,97,218,1)'></td>
+ <td width='1' style='background-color: rgba(27,97,213,1)'></td>
+ <td width='1' style='background-color: rgba(29,97,208,1)'></td>
+ <td width='1' style='background-color: rgba(32,96,202,1)'></td>
+ <td width='1' style='background-color: rgba(34,95,197,1)'></td>
+ <td width='1' style='background-color: rgba(36,95,192,1)'></td>
+ <td width='1' style='background-color: rgba(39,95,187,1)'></td>
+ <td width='1' style='background-color: rgba(42,94,182,1)'></td>
+ <td width='1' style='background-color: rgba(44,94,176,1)'></td>
+ <td width='1' style='background-color: rgba(46,93,170,1)'></td>
+ <td width='1' style='background-color: rgba(49,93,166,1)'></td>
+ <td width='1' style='background-color: rgba(52,92,161,1)'></td>
+ <td width='1' style='background-color: rgba(54,92,155,1)'></td>
+ <td width='1' style='background-color: rgba(57,92,150,1)'></td>
+ <td width='1' style='background-color: rgba(59,91,144,1)'></td>
+ <td width='1' style='background-color: rgba(61,91,139,1)'></td>
+ <td width='1' style='background-color: rgba(64,90,135,1)'></td>
+ <td width='1' style='background-color: rgba(67,90,129,1)'></td>
+ <td width='1' style='background-color: rgba(69,90,124,1)'></td>
+ <td width='1' style='background-color: rgba(71,89,118,1)'></td>
+ <td width='1' style='background-color: rgba(74,88,113,1)'></td>
+ <td width='1' style='background-color: rgba(76,88,107,1)'></td>
+ <td width='1' style='background-color: rgba(79,88,103,1)'></td>
+ <td width='1' style='background-color: rgba(82,88,98,1)'></td>
+ <td width='1' style='background-color: rgba(83,87,92,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(12,99,244,1)'></td>
+ <td width='1' style='background-color: rgba(13,98,238,1)'></td>
+ <td width='1' style='background-color: rgba(15,97,232,1)'></td>
+ <td width='1' style='background-color: rgba(18,96,228,1)'></td>
+ <td width='1' style='background-color: rgba(19,95,221,1)'></td>
+ <td width='1' style='background-color: rgba(21,94,215,1)'></td>
+ <td width='1' style='background-color: rgba(24,94,210,1)'></td>
+ <td width='1' style='background-color: rgba(25,93,204,1)'></td>
+ <td width='1' style='background-color: rgba(27,91,197,1)'></td>
+ <td width='1' style='background-color: rgba(30,91,193,1)'></td>
+ <td width='1' style='background-color: rgba(31,90,187,1)'></td>
+ <td width='1' style='background-color: rgba(33,89,181,1)'></td>
+ <td width='1' style='background-color: rgba(35,87,175,1)'></td>
+ <td width='1' style='background-color: rgba(37,87,169,1)'></td>
+ <td width='1' style='background-color: rgba(39,86,163,1)'></td>
+ <td width='1' style='background-color: rgba(41,85,158,1)'></td>
+ <td width='1' style='background-color: rgba(44,84,153,1)'></td>
+ <td width='1' style='background-color: rgba(45,83,146,1)'></td>
+ <td width='1' style='background-color: rgba(48,83,141,1)'></td>
+ <td width='1' style='background-color: rgba(50,82,135,1)'></td>
+ <td width='1' style='background-color: rgba(51,81,129,1)'></td>
+ <td width='1' style='background-color: rgba(53,79,124,1)'></td>
+ <td width='1' style='background-color: rgba(56,79,118,1)'></td>
+ <td width='1' style='background-color: rgba(57,78,112,1)'></td>
+ <td width='1' style='background-color: rgba(59,77,106,1)'></td>
+ <td width='1' style='background-color: rgba(62,76,101,1)'></td>
+ <td width='1' style='background-color: rgba(63,75,94,1)'></td>
+ <td width='1' style='background-color: rgba(65,74,89,1)'></td>
+ <td width='1' style='background-color: rgba(68,74,84,1)'></td>
+ <td width='1' style='background-color: rgba(69,73,78,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(11,98,243,1)'></td>
+ <td width='1' style='background-color: rgba(12,97,237,1)'></td>
+ <td width='1' style='background-color: rgba(13,95,230,1)'></td>
+ <td width='1' style='background-color: rgba(15,93,225,1)'></td>
+ <td width='1' style='background-color: rgba(16,92,218,1)'></td>
+ <td width='1' style='background-color: rgba(18,91,212,1)'></td>
+ <td width='1' style='background-color: rgba(19,89,205,1)'></td>
+ <td width='1' style='background-color: rgba(20,88,199,1)'></td>
+ <td width='1' style='background-color: rgba(22,86,192,1)'></td>
+ <td width='1' style='background-color: rgba(24,85,187,1)'></td>
+ <td width='1' style='background-color: rgba(24,83,180,1)'></td>
+ <td width='1' style='background-color: rgba(26,82,174,1)'></td>
+ <td width='1' style='background-color: rgba(28,80,168,1)'></td>
+ <td width='1' style='background-color: rgba(28,78,160,1)'></td>
+ <td width='1' style='background-color: rgba(30,77,154,1)'></td>
+ <td width='1' style='background-color: rgba(32,76,149,1)'></td>
+ <td width='1' style='background-color: rgba(33,73,142,1)'></td>
+ <td width='1' style='background-color: rgba(34,72,135,1)'></td>
+ <td width='1' style='background-color: rgba(36,71,129,1)'></td>
+ <td width='1' style='background-color: rgba(38,70,123,1)'></td>
+ <td width='1' style='background-color: rgba(38,68,116,1)'></td>
+ <td width='1' style='background-color: rgba(40,66,111,1)'></td>
+ <td width='1' style='background-color: rgba(42,65,104,1)'></td>
+ <td width='1' style='background-color: rgba(42,63,97,1)'></td>
+ <td width='1' style='background-color: rgba(44,62,91,1)'></td>
+ <td width='1' style='background-color: rgba(46,60,85,1)'></td>
+ <td width='1' style='background-color: rgba(47,59,78,1)'></td>
+ <td width='1' style='background-color: rgba(48,57,72,1)'></td>
+ <td width='1' style='background-color: rgba(50,56,66,1)'></td>
+ <td width='1' style='background-color: rgba(51,55,60,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,97,242,1)'></td>
+ <td width='1' style='background-color: rgba(9,94,234,1)'></td>
+ <td width='1' style='background-color: rgba(9,91,226,1)'></td>
+ <td width='1' style='background-color: rgba(9,87,219,1)'></td>
+ <td width='1' style='background-color: rgba(8,84,210,1)'></td>
+ <td width='1' style='background-color: rgba(8,81,202,1)'></td>
+ <td width='1' style='background-color: rgba(8,78,194,1)'></td>
+ <td width='1' style='background-color: rgba(7,75,186,1)'></td>
+ <td width='1' style='background-color: rgba(7,71,177,1)'></td>
+ <td width='1' style='background-color: rgba(7,68,170,1)'></td>
+ <td width='1' style='background-color: rgba(6,65,162,1)'></td>
+ <td width='1' style='background-color: rgba(6,62,154,1)'></td>
+ <td width='1' style='background-color: rgba(6,58,146,1)'></td>
+ <td width='1' style='background-color: rgba(5,55,137,1)'></td>
+ <td width='1' style='background-color: rgba(5,52,129,1)'></td>
+ <td width='1' style='background-color: rgba(5,49,122,1)'></td>
+ <td width='1' style='background-color: rgba(5,45,114,1)'></td>
+ <td width='1' style='background-color: rgba(4,42,105,1)'></td>
+ <td width='1' style='background-color: rgba(4,39,97,1)'></td>
+ <td width='1' style='background-color: rgba(4,36,89,1)'></td>
+ <td width='1' style='background-color: rgba(3,33,81,1)'></td>
+ <td width='1' style='background-color: rgba(3,29,74,1)'></td>
+ <td width='1' style='background-color: rgba(3,26,65,1)'></td>
+ <td width='1' style='background-color: rgba(2,23,57,1)'></td>
+ <td width='1' style='background-color: rgba(2,20,49,1)'></td>
+ <td width='1' style='background-color: rgba(2,16,41,1)'></td>
+ <td width='1' style='background-color: rgba(1,13,32,1)'></td>
+ <td width='1' style='background-color: rgba(1,10,25,1)'></td>
+ <td width='1' style='background-color: rgba(1,7,17,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-background/bg__4a16.html b/image/test/reftest/pngsuite-background/bg__4a16.html
new file mode 100644
index 0000000000..b15b280f1c
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/bg__4a16.html
@@ -0,0 +1,1092 @@
+<html><body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,94,234,1)'></td>
+ <td width='1' style='background-color: rgba(13,98,238,1)'></td>
+ <td width='1' style='background-color: rgba(15,100,240,1)'></td>
+ <td width='1' style='background-color: rgba(16,101,241,1)'></td>
+ <td width='1' style='background-color: rgba(17,102,242,1)'></td>
+ <td width='1' style='background-color: rgba(18,103,243,1)'></td>
+ <td width='1' style='background-color: rgba(19,104,244,1)'></td>
+ <td width='1' style='background-color: rgba(20,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(22,107,247,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(22,107,247,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(20,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(19,104,244,1)'></td>
+ <td width='1' style='background-color: rgba(18,103,243,1)'></td>
+ <td width='1' style='background-color: rgba(17,102,242,1)'></td>
+ <td width='1' style='background-color: rgba(16,101,241,1)'></td>
+ <td width='1' style='background-color: rgba(15,100,240,1)'></td>
+ <td width='1' style='background-color: rgba(13,98,238,1)'></td>
+ <td width='1' style='background-color: rgba(9,94,234,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(13,98,238,1)'></td>
+ <td width='1' style='background-color: rgba(9,87,218,1)'></td>
+ <td width='1' style='background-color: rgba(19,97,228,1)'></td>
+ <td width='1' style='background-color: rgba(22,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(25,103,234,1)'></td>
+ <td width='1' style='background-color: rgba(28,106,237,1)'></td>
+ <td width='1' style='background-color: rgba(29,107,238,1)'></td>
+ <td width='1' style='background-color: rgba(31,109,240,1)'></td>
+ <td width='1' style='background-color: rgba(33,111,242,1)'></td>
+ <td width='1' style='background-color: rgba(35,113,244,1)'></td>
+ <td width='1' style='background-color: rgba(36,114,245,1)'></td>
+ <td width='1' style='background-color: rgba(37,115,246,1)'></td>
+ <td width='1' style='background-color: rgba(39,117,248,1)'></td>
+ <td width='1' style='background-color: rgba(40,118,249,1)'></td>
+ <td width='1' style='background-color: rgba(41,119,250,1)'></td>
+ <td width='1' style='background-color: rgba(41,119,250,1)'></td>
+ <td width='1' style='background-color: rgba(40,118,249,1)'></td>
+ <td width='1' style='background-color: rgba(39,117,248,1)'></td>
+ <td width='1' style='background-color: rgba(37,115,246,1)'></td>
+ <td width='1' style='background-color: rgba(36,114,245,1)'></td>
+ <td width='1' style='background-color: rgba(35,113,244,1)'></td>
+ <td width='1' style='background-color: rgba(33,111,242,1)'></td>
+ <td width='1' style='background-color: rgba(31,109,240,1)'></td>
+ <td width='1' style='background-color: rgba(29,107,238,1)'></td>
+ <td width='1' style='background-color: rgba(28,106,237,1)'></td>
+ <td width='1' style='background-color: rgba(25,103,234,1)'></td>
+ <td width='1' style='background-color: rgba(22,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(19,97,228,1)'></td>
+ <td width='1' style='background-color: rgba(9,87,218,1)'></td>
+ <td width='1' style='background-color: rgba(13,98,238,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(15,100,240,1)'></td>
+ <td width='1' style='background-color: rgba(19,97,228,1)'></td>
+ <td width='1' style='background-color: rgba(8,81,202,1)'></td>
+ <td width='1' style='background-color: rgba(23,96,217,1)'></td>
+ <td width='1' style='background-color: rgba(29,102,223,1)'></td>
+ <td width='1' style='background-color: rgba(33,106,227,1)'></td>
+ <td width='1' style='background-color: rgba(37,110,231,1)'></td>
+ <td width='1' style='background-color: rgba(40,113,234,1)'></td>
+ <td width='1' style='background-color: rgba(43,116,237,1)'></td>
+ <td width='1' style='background-color: rgba(45,118,239,1)'></td>
+ <td width='1' style='background-color: rgba(47,120,241,1)'></td>
+ <td width='1' style='background-color: rgba(50,123,244,1)'></td>
+ <td width='1' style='background-color: rgba(52,125,246,1)'></td>
+ <td width='1' style='background-color: rgba(54,127,248,1)'></td>
+ <td width='1' style='background-color: rgba(56,129,250,1)'></td>
+ <td width='1' style='background-color: rgba(56,129,250,1)'></td>
+ <td width='1' style='background-color: rgba(54,127,248,1)'></td>
+ <td width='1' style='background-color: rgba(52,125,246,1)'></td>
+ <td width='1' style='background-color: rgba(50,123,244,1)'></td>
+ <td width='1' style='background-color: rgba(47,120,241,1)'></td>
+ <td width='1' style='background-color: rgba(45,118,239,1)'></td>
+ <td width='1' style='background-color: rgba(43,116,237,1)'></td>
+ <td width='1' style='background-color: rgba(40,113,234,1)'></td>
+ <td width='1' style='background-color: rgba(37,110,231,1)'></td>
+ <td width='1' style='background-color: rgba(33,106,227,1)'></td>
+ <td width='1' style='background-color: rgba(29,102,223,1)'></td>
+ <td width='1' style='background-color: rgba(23,96,217,1)'></td>
+ <td width='1' style='background-color: rgba(8,81,202,1)'></td>
+ <td width='1' style='background-color: rgba(19,97,228,1)'></td>
+ <td width='1' style='background-color: rgba(15,100,240,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(16,101,241,1)'></td>
+ <td width='1' style='background-color: rgba(22,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(23,96,217,1)'></td>
+ <td width='1' style='background-color: rgba(7,74,185,1)'></td>
+ <td width='1' style='background-color: rgba(28,95,206,1)'></td>
+ <td width='1' style='background-color: rgba(36,103,214,1)'></td>
+ <td width='1' style='background-color: rgba(42,109,220,1)'></td>
+ <td width='1' style='background-color: rgba(47,114,225,1)'></td>
+ <td width='1' style='background-color: rgba(52,119,230,1)'></td>
+ <td width='1' style='background-color: rgba(56,123,234,1)'></td>
+ <td width='1' style='background-color: rgba(59,126,237,1)'></td>
+ <td width='1' style='background-color: rgba(62,129,240,1)'></td>
+ <td width='1' style='background-color: rgba(66,133,244,1)'></td>
+ <td width='1' style='background-color: rgba(68,135,246,1)'></td>
+ <td width='1' style='background-color: rgba(71,138,249,1)'></td>
+ <td width='1' style='background-color: rgba(71,138,249,1)'></td>
+ <td width='1' style='background-color: rgba(68,135,246,1)'></td>
+ <td width='1' style='background-color: rgba(66,133,244,1)'></td>
+ <td width='1' style='background-color: rgba(62,129,240,1)'></td>
+ <td width='1' style='background-color: rgba(59,126,237,1)'></td>
+ <td width='1' style='background-color: rgba(56,123,234,1)'></td>
+ <td width='1' style='background-color: rgba(52,119,230,1)'></td>
+ <td width='1' style='background-color: rgba(47,114,225,1)'></td>
+ <td width='1' style='background-color: rgba(42,109,220,1)'></td>
+ <td width='1' style='background-color: rgba(36,103,214,1)'></td>
+ <td width='1' style='background-color: rgba(28,95,206,1)'></td>
+ <td width='1' style='background-color: rgba(7,74,185,1)'></td>
+ <td width='1' style='background-color: rgba(23,96,217,1)'></td>
+ <td width='1' style='background-color: rgba(22,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(16,101,241,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(17,102,242,1)'></td>
+ <td width='1' style='background-color: rgba(25,103,234,1)'></td>
+ <td width='1' style='background-color: rgba(29,102,223,1)'></td>
+ <td width='1' style='background-color: rgba(28,95,206,1)'></td>
+ <td width='1' style='background-color: rgba(7,68,170,1)'></td>
+ <td width='1' style='background-color: rgba(34,95,197,1)'></td>
+ <td width='1' style='background-color: rgba(45,106,208,1)'></td>
+ <td width='1' style='background-color: rgba(53,114,216,1)'></td>
+ <td width='1' style='background-color: rgba(59,120,222,1)'></td>
+ <td width='1' style='background-color: rgba(65,126,228,1)'></td>
+ <td width='1' style='background-color: rgba(70,131,233,1)'></td>
+ <td width='1' style='background-color: rgba(75,136,238,1)'></td>
+ <td width='1' style='background-color: rgba(79,140,242,1)'></td>
+ <td width='1' style='background-color: rgba(83,144,246,1)'></td>
+ <td width='1' style='background-color: rgba(87,148,250,1)'></td>
+ <td width='1' style='background-color: rgba(87,148,250,1)'></td>
+ <td width='1' style='background-color: rgba(83,144,246,1)'></td>
+ <td width='1' style='background-color: rgba(79,140,242,1)'></td>
+ <td width='1' style='background-color: rgba(75,136,238,1)'></td>
+ <td width='1' style='background-color: rgba(70,131,233,1)'></td>
+ <td width='1' style='background-color: rgba(65,126,228,1)'></td>
+ <td width='1' style='background-color: rgba(59,120,222,1)'></td>
+ <td width='1' style='background-color: rgba(53,114,216,1)'></td>
+ <td width='1' style='background-color: rgba(45,106,208,1)'></td>
+ <td width='1' style='background-color: rgba(34,95,197,1)'></td>
+ <td width='1' style='background-color: rgba(7,68,170,1)'></td>
+ <td width='1' style='background-color: rgba(28,95,206,1)'></td>
+ <td width='1' style='background-color: rgba(29,102,223,1)'></td>
+ <td width='1' style='background-color: rgba(25,103,234,1)'></td>
+ <td width='1' style='background-color: rgba(17,102,242,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(18,103,243,1)'></td>
+ <td width='1' style='background-color: rgba(28,106,237,1)'></td>
+ <td width='1' style='background-color: rgba(33,106,227,1)'></td>
+ <td width='1' style='background-color: rgba(36,103,214,1)'></td>
+ <td width='1' style='background-color: rgba(34,95,197,1)'></td>
+ <td width='1' style='background-color: rgba(6,61,153,1)'></td>
+ <td width='1' style='background-color: rgba(41,96,188,1)'></td>
+ <td width='1' style='background-color: rgba(54,109,201,1)'></td>
+ <td width='1' style='background-color: rgba(64,119,211,1)'></td>
+ <td width='1' style='background-color: rgba(72,127,219,1)'></td>
+ <td width='1' style='background-color: rgba(79,134,226,1)'></td>
+ <td width='1' style='background-color: rgba(86,141,233,1)'></td>
+ <td width='1' style='background-color: rgba(92,147,239,1)'></td>
+ <td width='1' style='background-color: rgba(97,152,244,1)'></td>
+ <td width='1' style='background-color: rgba(102,157,249,1)'></td>
+ <td width='1' style='background-color: rgba(102,157,249,1)'></td>
+ <td width='1' style='background-color: rgba(97,152,244,1)'></td>
+ <td width='1' style='background-color: rgba(92,147,239,1)'></td>
+ <td width='1' style='background-color: rgba(86,141,233,1)'></td>
+ <td width='1' style='background-color: rgba(79,134,226,1)'></td>
+ <td width='1' style='background-color: rgba(72,127,219,1)'></td>
+ <td width='1' style='background-color: rgba(64,119,211,1)'></td>
+ <td width='1' style='background-color: rgba(54,109,201,1)'></td>
+ <td width='1' style='background-color: rgba(41,96,188,1)'></td>
+ <td width='1' style='background-color: rgba(6,61,153,1)'></td>
+ <td width='1' style='background-color: rgba(34,95,197,1)'></td>
+ <td width='1' style='background-color: rgba(36,103,214,1)'></td>
+ <td width='1' style='background-color: rgba(33,106,227,1)'></td>
+ <td width='1' style='background-color: rgba(28,106,237,1)'></td>
+ <td width='1' style='background-color: rgba(18,103,243,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(19,104,244,1)'></td>
+ <td width='1' style='background-color: rgba(29,107,238,1)'></td>
+ <td width='1' style='background-color: rgba(37,110,231,1)'></td>
+ <td width='1' style='background-color: rgba(42,109,220,1)'></td>
+ <td width='1' style='background-color: rgba(45,106,208,1)'></td>
+ <td width='1' style='background-color: rgba(41,96,188,1)'></td>
+ <td width='1' style='background-color: rgba(5,55,137,1)'></td>
+ <td width='1' style='background-color: rgba(48,98,180,1)'></td>
+ <td width='1' style='background-color: rgba(64,114,196,1)'></td>
+ <td width='1' style='background-color: rgba(76,126,208,1)'></td>
+ <td width='1' style='background-color: rgba(86,136,218,1)'></td>
+ <td width='1' style='background-color: rgba(95,145,227,1)'></td>
+ <td width='1' style='background-color: rgba(103,153,235,1)'></td>
+ <td width='1' style='background-color: rgba(110,160,242,1)'></td>
+ <td width='1' style='background-color: rgba(116,166,248,1)'></td>
+ <td width='1' style='background-color: rgba(116,166,248,1)'></td>
+ <td width='1' style='background-color: rgba(110,160,242,1)'></td>
+ <td width='1' style='background-color: rgba(103,153,235,1)'></td>
+ <td width='1' style='background-color: rgba(95,145,227,1)'></td>
+ <td width='1' style='background-color: rgba(86,136,218,1)'></td>
+ <td width='1' style='background-color: rgba(76,126,208,1)'></td>
+ <td width='1' style='background-color: rgba(64,114,196,1)'></td>
+ <td width='1' style='background-color: rgba(48,98,180,1)'></td>
+ <td width='1' style='background-color: rgba(5,55,137,1)'></td>
+ <td width='1' style='background-color: rgba(41,96,188,1)'></td>
+ <td width='1' style='background-color: rgba(45,106,208,1)'></td>
+ <td width='1' style='background-color: rgba(42,109,220,1)'></td>
+ <td width='1' style='background-color: rgba(37,110,231,1)'></td>
+ <td width='1' style='background-color: rgba(29,107,238,1)'></td>
+ <td width='1' style='background-color: rgba(19,104,244,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(20,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(31,109,240,1)'></td>
+ <td width='1' style='background-color: rgba(40,113,234,1)'></td>
+ <td width='1' style='background-color: rgba(47,114,225,1)'></td>
+ <td width='1' style='background-color: rgba(53,114,216,1)'></td>
+ <td width='1' style='background-color: rgba(54,109,201,1)'></td>
+ <td width='1' style='background-color: rgba(48,98,180,1)'></td>
+ <td width='1' style='background-color: rgba(5,48,121,1)'></td>
+ <td width='1' style='background-color: rgba(57,100,173,1)'></td>
+ <td width='1' style='background-color: rgba(77,120,193,1)'></td>
+ <td width='1' style='background-color: rgba(91,134,207,1)'></td>
+ <td width='1' style='background-color: rgba(104,147,220,1)'></td>
+ <td width='1' style='background-color: rgba(114,157,230,1)'></td>
+ <td width='1' style='background-color: rgba(124,167,240,1)'></td>
+ <td width='1' style='background-color: rgba(132,175,248,1)'></td>
+ <td width='1' style='background-color: rgba(132,175,248,1)'></td>
+ <td width='1' style='background-color: rgba(124,167,240,1)'></td>
+ <td width='1' style='background-color: rgba(114,157,230,1)'></td>
+ <td width='1' style='background-color: rgba(104,147,220,1)'></td>
+ <td width='1' style='background-color: rgba(91,134,207,1)'></td>
+ <td width='1' style='background-color: rgba(77,120,193,1)'></td>
+ <td width='1' style='background-color: rgba(57,100,173,1)'></td>
+ <td width='1' style='background-color: rgba(5,48,121,1)'></td>
+ <td width='1' style='background-color: rgba(48,98,180,1)'></td>
+ <td width='1' style='background-color: rgba(54,109,201,1)'></td>
+ <td width='1' style='background-color: rgba(53,114,216,1)'></td>
+ <td width='1' style='background-color: rgba(47,114,225,1)'></td>
+ <td width='1' style='background-color: rgba(40,113,234,1)'></td>
+ <td width='1' style='background-color: rgba(31,109,240,1)'></td>
+ <td width='1' style='background-color: rgba(20,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(33,111,242,1)'></td>
+ <td width='1' style='background-color: rgba(43,116,237,1)'></td>
+ <td width='1' style='background-color: rgba(52,119,230,1)'></td>
+ <td width='1' style='background-color: rgba(59,120,222,1)'></td>
+ <td width='1' style='background-color: rgba(64,119,211,1)'></td>
+ <td width='1' style='background-color: rgba(64,114,196,1)'></td>
+ <td width='1' style='background-color: rgba(57,100,173,1)'></td>
+ <td width='1' style='background-color: rgba(4,42,105,1)'></td>
+ <td width='1' style='background-color: rgba(67,105,168,1)'></td>
+ <td width='1' style='background-color: rgba(90,128,191,1)'></td>
+ <td width='1' style='background-color: rgba(107,145,208,1)'></td>
+ <td width='1' style='background-color: rgba(122,160,223,1)'></td>
+ <td width='1' style='background-color: rgba(135,173,236,1)'></td>
+ <td width='1' style='background-color: rgba(146,184,247,1)'></td>
+ <td width='1' style='background-color: rgba(146,184,247,1)'></td>
+ <td width='1' style='background-color: rgba(135,173,236,1)'></td>
+ <td width='1' style='background-color: rgba(122,160,223,1)'></td>
+ <td width='1' style='background-color: rgba(107,145,208,1)'></td>
+ <td width='1' style='background-color: rgba(90,128,191,1)'></td>
+ <td width='1' style='background-color: rgba(67,105,168,1)'></td>
+ <td width='1' style='background-color: rgba(4,42,105,1)'></td>
+ <td width='1' style='background-color: rgba(57,100,173,1)'></td>
+ <td width='1' style='background-color: rgba(64,114,196,1)'></td>
+ <td width='1' style='background-color: rgba(64,119,211,1)'></td>
+ <td width='1' style='background-color: rgba(59,120,222,1)'></td>
+ <td width='1' style='background-color: rgba(52,119,230,1)'></td>
+ <td width='1' style='background-color: rgba(43,116,237,1)'></td>
+ <td width='1' style='background-color: rgba(33,111,242,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(35,113,244,1)'></td>
+ <td width='1' style='background-color: rgba(45,118,239,1)'></td>
+ <td width='1' style='background-color: rgba(56,123,234,1)'></td>
+ <td width='1' style='background-color: rgba(65,126,228,1)'></td>
+ <td width='1' style='background-color: rgba(72,127,219,1)'></td>
+ <td width='1' style='background-color: rgba(76,126,208,1)'></td>
+ <td width='1' style='background-color: rgba(77,120,193,1)'></td>
+ <td width='1' style='background-color: rgba(67,105,168,1)'></td>
+ <td width='1' style='background-color: rgba(4,35,88,1)'></td>
+ <td width='1' style='background-color: rgba(79,110,163,1)'></td>
+ <td width='1' style='background-color: rgba(108,139,192,1)'></td>
+ <td width='1' style='background-color: rgba(129,160,213,1)'></td>
+ <td width='1' style='background-color: rgba(147,178,231,1)'></td>
+ <td width='1' style='background-color: rgba(161,192,245,1)'></td>
+ <td width='1' style='background-color: rgba(161,192,245,1)'></td>
+ <td width='1' style='background-color: rgba(147,178,231,1)'></td>
+ <td width='1' style='background-color: rgba(129,160,213,1)'></td>
+ <td width='1' style='background-color: rgba(108,139,192,1)'></td>
+ <td width='1' style='background-color: rgba(79,110,163,1)'></td>
+ <td width='1' style='background-color: rgba(4,35,88,1)'></td>
+ <td width='1' style='background-color: rgba(67,105,168,1)'></td>
+ <td width='1' style='background-color: rgba(77,120,193,1)'></td>
+ <td width='1' style='background-color: rgba(76,126,208,1)'></td>
+ <td width='1' style='background-color: rgba(72,127,219,1)'></td>
+ <td width='1' style='background-color: rgba(65,126,228,1)'></td>
+ <td width='1' style='background-color: rgba(56,123,234,1)'></td>
+ <td width='1' style='background-color: rgba(45,118,239,1)'></td>
+ <td width='1' style='background-color: rgba(35,113,244,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(22,107,247,1)'></td>
+ <td width='1' style='background-color: rgba(36,114,245,1)'></td>
+ <td width='1' style='background-color: rgba(47,120,241,1)'></td>
+ <td width='1' style='background-color: rgba(59,126,237,1)'></td>
+ <td width='1' style='background-color: rgba(70,131,233,1)'></td>
+ <td width='1' style='background-color: rgba(79,134,226,1)'></td>
+ <td width='1' style='background-color: rgba(86,136,218,1)'></td>
+ <td width='1' style='background-color: rgba(91,134,207,1)'></td>
+ <td width='1' style='background-color: rgba(90,128,191,1)'></td>
+ <td width='1' style='background-color: rgba(79,110,163,1)'></td>
+ <td width='1' style='background-color: rgba(3,29,73,1)'></td>
+ <td width='1' style='background-color: rgba(94,120,164,1)'></td>
+ <td width='1' style='background-color: rgba(127,153,197,1)'></td>
+ <td width='1' style='background-color: rgba(153,179,223,1)'></td>
+ <td width='1' style='background-color: rgba(174,200,244,1)'></td>
+ <td width='1' style='background-color: rgba(174,200,244,1)'></td>
+ <td width='1' style='background-color: rgba(153,179,223,1)'></td>
+ <td width='1' style='background-color: rgba(127,153,197,1)'></td>
+ <td width='1' style='background-color: rgba(94,120,164,1)'></td>
+ <td width='1' style='background-color: rgba(3,29,73,1)'></td>
+ <td width='1' style='background-color: rgba(79,110,163,1)'></td>
+ <td width='1' style='background-color: rgba(90,128,191,1)'></td>
+ <td width='1' style='background-color: rgba(91,134,207,1)'></td>
+ <td width='1' style='background-color: rgba(86,136,218,1)'></td>
+ <td width='1' style='background-color: rgba(79,134,226,1)'></td>
+ <td width='1' style='background-color: rgba(70,131,233,1)'></td>
+ <td width='1' style='background-color: rgba(59,126,237,1)'></td>
+ <td width='1' style='background-color: rgba(47,120,241,1)'></td>
+ <td width='1' style='background-color: rgba(36,114,245,1)'></td>
+ <td width='1' style='background-color: rgba(22,107,247,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(37,115,246,1)'></td>
+ <td width='1' style='background-color: rgba(50,123,244,1)'></td>
+ <td width='1' style='background-color: rgba(62,129,240,1)'></td>
+ <td width='1' style='background-color: rgba(75,136,238,1)'></td>
+ <td width='1' style='background-color: rgba(86,141,233,1)'></td>
+ <td width='1' style='background-color: rgba(95,145,227,1)'></td>
+ <td width='1' style='background-color: rgba(104,147,220,1)'></td>
+ <td width='1' style='background-color: rgba(107,145,208,1)'></td>
+ <td width='1' style='background-color: rgba(108,139,192,1)'></td>
+ <td width='1' style='background-color: rgba(94,120,164,1)'></td>
+ <td width='1' style='background-color: rgba(2,23,57,1)'></td>
+ <td width='1' style='background-color: rgba(113,134,168,1)'></td>
+ <td width='1' style='background-color: rgba(154,175,209,1)'></td>
+ <td width='1' style='background-color: rgba(185,206,240,1)'></td>
+ <td width='1' style='background-color: rgba(185,206,240,1)'></td>
+ <td width='1' style='background-color: rgba(154,175,209,1)'></td>
+ <td width='1' style='background-color: rgba(113,134,168,1)'></td>
+ <td width='1' style='background-color: rgba(2,23,57,1)'></td>
+ <td width='1' style='background-color: rgba(94,120,164,1)'></td>
+ <td width='1' style='background-color: rgba(108,139,192,1)'></td>
+ <td width='1' style='background-color: rgba(107,145,208,1)'></td>
+ <td width='1' style='background-color: rgba(104,147,220,1)'></td>
+ <td width='1' style='background-color: rgba(95,145,227,1)'></td>
+ <td width='1' style='background-color: rgba(86,141,233,1)'></td>
+ <td width='1' style='background-color: rgba(75,136,238,1)'></td>
+ <td width='1' style='background-color: rgba(62,129,240,1)'></td>
+ <td width='1' style='background-color: rgba(50,123,244,1)'></td>
+ <td width='1' style='background-color: rgba(37,115,246,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(39,117,248,1)'></td>
+ <td width='1' style='background-color: rgba(52,125,246,1)'></td>
+ <td width='1' style='background-color: rgba(66,133,244,1)'></td>
+ <td width='1' style='background-color: rgba(79,140,242,1)'></td>
+ <td width='1' style='background-color: rgba(92,147,239,1)'></td>
+ <td width='1' style='background-color: rgba(103,153,235,1)'></td>
+ <td width='1' style='background-color: rgba(114,157,230,1)'></td>
+ <td width='1' style='background-color: rgba(122,160,223,1)'></td>
+ <td width='1' style='background-color: rgba(129,160,213,1)'></td>
+ <td width='1' style='background-color: rgba(127,153,197,1)'></td>
+ <td width='1' style='background-color: rgba(113,134,168,1)'></td>
+ <td width='1' style='background-color: rgba(2,16,40,1)'></td>
+ <td width='1' style='background-color: rgba(142,156,180,1)'></td>
+ <td width='1' style='background-color: rgba(195,209,233,1)'></td>
+ <td width='1' style='background-color: rgba(195,209,233,1)'></td>
+ <td width='1' style='background-color: rgba(142,156,180,1)'></td>
+ <td width='1' style='background-color: rgba(2,16,40,1)'></td>
+ <td width='1' style='background-color: rgba(113,134,168,1)'></td>
+ <td width='1' style='background-color: rgba(127,153,197,1)'></td>
+ <td width='1' style='background-color: rgba(129,160,213,1)'></td>
+ <td width='1' style='background-color: rgba(122,160,223,1)'></td>
+ <td width='1' style='background-color: rgba(114,157,230,1)'></td>
+ <td width='1' style='background-color: rgba(103,153,235,1)'></td>
+ <td width='1' style='background-color: rgba(92,147,239,1)'></td>
+ <td width='1' style='background-color: rgba(79,140,242,1)'></td>
+ <td width='1' style='background-color: rgba(66,133,244,1)'></td>
+ <td width='1' style='background-color: rgba(52,125,246,1)'></td>
+ <td width='1' style='background-color: rgba(39,117,248,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(40,118,249,1)'></td>
+ <td width='1' style='background-color: rgba(54,127,248,1)'></td>
+ <td width='1' style='background-color: rgba(68,135,246,1)'></td>
+ <td width='1' style='background-color: rgba(83,144,246,1)'></td>
+ <td width='1' style='background-color: rgba(97,152,244,1)'></td>
+ <td width='1' style='background-color: rgba(110,160,242,1)'></td>
+ <td width='1' style='background-color: rgba(124,167,240,1)'></td>
+ <td width='1' style='background-color: rgba(135,173,236,1)'></td>
+ <td width='1' style='background-color: rgba(147,178,231,1)'></td>
+ <td width='1' style='background-color: rgba(153,179,223,1)'></td>
+ <td width='1' style='background-color: rgba(154,175,209,1)'></td>
+ <td width='1' style='background-color: rgba(142,156,180,1)'></td>
+ <td width='1' style='background-color: rgba(1,10,25,1)'></td>
+ <td width='1' style='background-color: rgba(192,201,216,1)'></td>
+ <td width='1' style='background-color: rgba(192,201,216,1)'></td>
+ <td width='1' style='background-color: rgba(1,10,25,1)'></td>
+ <td width='1' style='background-color: rgba(142,156,180,1)'></td>
+ <td width='1' style='background-color: rgba(154,175,209,1)'></td>
+ <td width='1' style='background-color: rgba(153,179,223,1)'></td>
+ <td width='1' style='background-color: rgba(147,178,231,1)'></td>
+ <td width='1' style='background-color: rgba(135,173,236,1)'></td>
+ <td width='1' style='background-color: rgba(124,167,240,1)'></td>
+ <td width='1' style='background-color: rgba(110,160,242,1)'></td>
+ <td width='1' style='background-color: rgba(97,152,244,1)'></td>
+ <td width='1' style='background-color: rgba(83,144,246,1)'></td>
+ <td width='1' style='background-color: rgba(68,135,246,1)'></td>
+ <td width='1' style='background-color: rgba(54,127,248,1)'></td>
+ <td width='1' style='background-color: rgba(40,118,249,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(41,119,250,1)'></td>
+ <td width='1' style='background-color: rgba(56,129,250,1)'></td>
+ <td width='1' style='background-color: rgba(71,138,249,1)'></td>
+ <td width='1' style='background-color: rgba(87,148,250,1)'></td>
+ <td width='1' style='background-color: rgba(102,157,249,1)'></td>
+ <td width='1' style='background-color: rgba(116,166,248,1)'></td>
+ <td width='1' style='background-color: rgba(132,175,248,1)'></td>
+ <td width='1' style='background-color: rgba(146,184,247,1)'></td>
+ <td width='1' style='background-color: rgba(161,192,245,1)'></td>
+ <td width='1' style='background-color: rgba(174,200,244,1)'></td>
+ <td width='1' style='background-color: rgba(185,206,240,1)'></td>
+ <td width='1' style='background-color: rgba(195,209,233,1)'></td>
+ <td width='1' style='background-color: rgba(192,201,216,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,8,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,8,1)'></td>
+ <td width='1' style='background-color: rgba(192,201,216,1)'></td>
+ <td width='1' style='background-color: rgba(195,209,233,1)'></td>
+ <td width='1' style='background-color: rgba(185,206,240,1)'></td>
+ <td width='1' style='background-color: rgba(174,200,244,1)'></td>
+ <td width='1' style='background-color: rgba(161,192,245,1)'></td>
+ <td width='1' style='background-color: rgba(146,184,247,1)'></td>
+ <td width='1' style='background-color: rgba(132,175,248,1)'></td>
+ <td width='1' style='background-color: rgba(116,166,248,1)'></td>
+ <td width='1' style='background-color: rgba(102,157,249,1)'></td>
+ <td width='1' style='background-color: rgba(87,148,250,1)'></td>
+ <td width='1' style='background-color: rgba(71,138,249,1)'></td>
+ <td width='1' style='background-color: rgba(56,129,250,1)'></td>
+ <td width='1' style='background-color: rgba(41,119,250,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(41,119,250,1)'></td>
+ <td width='1' style='background-color: rgba(56,129,250,1)'></td>
+ <td width='1' style='background-color: rgba(71,138,249,1)'></td>
+ <td width='1' style='background-color: rgba(87,148,250,1)'></td>
+ <td width='1' style='background-color: rgba(102,157,249,1)'></td>
+ <td width='1' style='background-color: rgba(116,166,248,1)'></td>
+ <td width='1' style='background-color: rgba(132,175,248,1)'></td>
+ <td width='1' style='background-color: rgba(146,184,247,1)'></td>
+ <td width='1' style='background-color: rgba(161,192,245,1)'></td>
+ <td width='1' style='background-color: rgba(174,200,244,1)'></td>
+ <td width='1' style='background-color: rgba(185,206,240,1)'></td>
+ <td width='1' style='background-color: rgba(195,209,233,1)'></td>
+ <td width='1' style='background-color: rgba(192,201,216,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,8,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,8,1)'></td>
+ <td width='1' style='background-color: rgba(192,201,216,1)'></td>
+ <td width='1' style='background-color: rgba(195,209,233,1)'></td>
+ <td width='1' style='background-color: rgba(185,206,240,1)'></td>
+ <td width='1' style='background-color: rgba(174,200,244,1)'></td>
+ <td width='1' style='background-color: rgba(161,192,245,1)'></td>
+ <td width='1' style='background-color: rgba(146,184,247,1)'></td>
+ <td width='1' style='background-color: rgba(132,175,248,1)'></td>
+ <td width='1' style='background-color: rgba(116,166,248,1)'></td>
+ <td width='1' style='background-color: rgba(102,157,249,1)'></td>
+ <td width='1' style='background-color: rgba(87,148,250,1)'></td>
+ <td width='1' style='background-color: rgba(71,138,249,1)'></td>
+ <td width='1' style='background-color: rgba(56,129,250,1)'></td>
+ <td width='1' style='background-color: rgba(41,119,250,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(40,118,249,1)'></td>
+ <td width='1' style='background-color: rgba(54,127,248,1)'></td>
+ <td width='1' style='background-color: rgba(68,135,246,1)'></td>
+ <td width='1' style='background-color: rgba(83,144,246,1)'></td>
+ <td width='1' style='background-color: rgba(97,152,244,1)'></td>
+ <td width='1' style='background-color: rgba(110,160,242,1)'></td>
+ <td width='1' style='background-color: rgba(124,167,240,1)'></td>
+ <td width='1' style='background-color: rgba(135,173,236,1)'></td>
+ <td width='1' style='background-color: rgba(147,178,231,1)'></td>
+ <td width='1' style='background-color: rgba(153,179,223,1)'></td>
+ <td width='1' style='background-color: rgba(154,175,209,1)'></td>
+ <td width='1' style='background-color: rgba(142,156,180,1)'></td>
+ <td width='1' style='background-color: rgba(1,10,25,1)'></td>
+ <td width='1' style='background-color: rgba(192,201,216,1)'></td>
+ <td width='1' style='background-color: rgba(192,201,216,1)'></td>
+ <td width='1' style='background-color: rgba(1,10,25,1)'></td>
+ <td width='1' style='background-color: rgba(142,156,180,1)'></td>
+ <td width='1' style='background-color: rgba(154,175,209,1)'></td>
+ <td width='1' style='background-color: rgba(153,179,223,1)'></td>
+ <td width='1' style='background-color: rgba(147,178,231,1)'></td>
+ <td width='1' style='background-color: rgba(135,173,236,1)'></td>
+ <td width='1' style='background-color: rgba(124,167,240,1)'></td>
+ <td width='1' style='background-color: rgba(110,160,242,1)'></td>
+ <td width='1' style='background-color: rgba(97,152,244,1)'></td>
+ <td width='1' style='background-color: rgba(83,144,246,1)'></td>
+ <td width='1' style='background-color: rgba(68,135,246,1)'></td>
+ <td width='1' style='background-color: rgba(54,127,248,1)'></td>
+ <td width='1' style='background-color: rgba(40,118,249,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(39,117,248,1)'></td>
+ <td width='1' style='background-color: rgba(52,125,246,1)'></td>
+ <td width='1' style='background-color: rgba(66,133,244,1)'></td>
+ <td width='1' style='background-color: rgba(79,140,242,1)'></td>
+ <td width='1' style='background-color: rgba(92,147,239,1)'></td>
+ <td width='1' style='background-color: rgba(103,153,235,1)'></td>
+ <td width='1' style='background-color: rgba(114,157,230,1)'></td>
+ <td width='1' style='background-color: rgba(122,160,223,1)'></td>
+ <td width='1' style='background-color: rgba(129,160,213,1)'></td>
+ <td width='1' style='background-color: rgba(127,153,197,1)'></td>
+ <td width='1' style='background-color: rgba(113,134,168,1)'></td>
+ <td width='1' style='background-color: rgba(2,16,40,1)'></td>
+ <td width='1' style='background-color: rgba(142,156,180,1)'></td>
+ <td width='1' style='background-color: rgba(195,209,233,1)'></td>
+ <td width='1' style='background-color: rgba(195,209,233,1)'></td>
+ <td width='1' style='background-color: rgba(142,156,180,1)'></td>
+ <td width='1' style='background-color: rgba(2,16,40,1)'></td>
+ <td width='1' style='background-color: rgba(113,134,168,1)'></td>
+ <td width='1' style='background-color: rgba(127,153,197,1)'></td>
+ <td width='1' style='background-color: rgba(129,160,213,1)'></td>
+ <td width='1' style='background-color: rgba(122,160,223,1)'></td>
+ <td width='1' style='background-color: rgba(114,157,230,1)'></td>
+ <td width='1' style='background-color: rgba(103,153,235,1)'></td>
+ <td width='1' style='background-color: rgba(92,147,239,1)'></td>
+ <td width='1' style='background-color: rgba(79,140,242,1)'></td>
+ <td width='1' style='background-color: rgba(66,133,244,1)'></td>
+ <td width='1' style='background-color: rgba(52,125,246,1)'></td>
+ <td width='1' style='background-color: rgba(39,117,248,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(37,115,246,1)'></td>
+ <td width='1' style='background-color: rgba(50,123,244,1)'></td>
+ <td width='1' style='background-color: rgba(62,129,240,1)'></td>
+ <td width='1' style='background-color: rgba(75,136,238,1)'></td>
+ <td width='1' style='background-color: rgba(86,141,233,1)'></td>
+ <td width='1' style='background-color: rgba(95,145,227,1)'></td>
+ <td width='1' style='background-color: rgba(104,147,220,1)'></td>
+ <td width='1' style='background-color: rgba(107,145,208,1)'></td>
+ <td width='1' style='background-color: rgba(108,139,192,1)'></td>
+ <td width='1' style='background-color: rgba(94,120,164,1)'></td>
+ <td width='1' style='background-color: rgba(2,23,57,1)'></td>
+ <td width='1' style='background-color: rgba(113,134,168,1)'></td>
+ <td width='1' style='background-color: rgba(154,175,209,1)'></td>
+ <td width='1' style='background-color: rgba(185,206,240,1)'></td>
+ <td width='1' style='background-color: rgba(185,206,240,1)'></td>
+ <td width='1' style='background-color: rgba(154,175,209,1)'></td>
+ <td width='1' style='background-color: rgba(113,134,168,1)'></td>
+ <td width='1' style='background-color: rgba(2,23,57,1)'></td>
+ <td width='1' style='background-color: rgba(94,120,164,1)'></td>
+ <td width='1' style='background-color: rgba(108,139,192,1)'></td>
+ <td width='1' style='background-color: rgba(107,145,208,1)'></td>
+ <td width='1' style='background-color: rgba(104,147,220,1)'></td>
+ <td width='1' style='background-color: rgba(95,145,227,1)'></td>
+ <td width='1' style='background-color: rgba(86,141,233,1)'></td>
+ <td width='1' style='background-color: rgba(75,136,238,1)'></td>
+ <td width='1' style='background-color: rgba(62,129,240,1)'></td>
+ <td width='1' style='background-color: rgba(50,123,244,1)'></td>
+ <td width='1' style='background-color: rgba(37,115,246,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(22,107,247,1)'></td>
+ <td width='1' style='background-color: rgba(36,114,245,1)'></td>
+ <td width='1' style='background-color: rgba(47,120,241,1)'></td>
+ <td width='1' style='background-color: rgba(59,126,237,1)'></td>
+ <td width='1' style='background-color: rgba(70,131,233,1)'></td>
+ <td width='1' style='background-color: rgba(79,134,226,1)'></td>
+ <td width='1' style='background-color: rgba(86,136,218,1)'></td>
+ <td width='1' style='background-color: rgba(91,134,207,1)'></td>
+ <td width='1' style='background-color: rgba(90,128,191,1)'></td>
+ <td width='1' style='background-color: rgba(79,110,163,1)'></td>
+ <td width='1' style='background-color: rgba(3,29,73,1)'></td>
+ <td width='1' style='background-color: rgba(94,120,164,1)'></td>
+ <td width='1' style='background-color: rgba(127,153,197,1)'></td>
+ <td width='1' style='background-color: rgba(153,179,223,1)'></td>
+ <td width='1' style='background-color: rgba(174,200,244,1)'></td>
+ <td width='1' style='background-color: rgba(174,200,244,1)'></td>
+ <td width='1' style='background-color: rgba(153,179,223,1)'></td>
+ <td width='1' style='background-color: rgba(127,153,197,1)'></td>
+ <td width='1' style='background-color: rgba(94,120,164,1)'></td>
+ <td width='1' style='background-color: rgba(3,29,73,1)'></td>
+ <td width='1' style='background-color: rgba(79,110,163,1)'></td>
+ <td width='1' style='background-color: rgba(90,128,191,1)'></td>
+ <td width='1' style='background-color: rgba(91,134,207,1)'></td>
+ <td width='1' style='background-color: rgba(86,136,218,1)'></td>
+ <td width='1' style='background-color: rgba(79,134,226,1)'></td>
+ <td width='1' style='background-color: rgba(70,131,233,1)'></td>
+ <td width='1' style='background-color: rgba(59,126,237,1)'></td>
+ <td width='1' style='background-color: rgba(47,120,241,1)'></td>
+ <td width='1' style='background-color: rgba(36,114,245,1)'></td>
+ <td width='1' style='background-color: rgba(22,107,247,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(35,113,244,1)'></td>
+ <td width='1' style='background-color: rgba(45,118,239,1)'></td>
+ <td width='1' style='background-color: rgba(56,123,234,1)'></td>
+ <td width='1' style='background-color: rgba(65,126,228,1)'></td>
+ <td width='1' style='background-color: rgba(72,127,219,1)'></td>
+ <td width='1' style='background-color: rgba(76,126,208,1)'></td>
+ <td width='1' style='background-color: rgba(77,120,193,1)'></td>
+ <td width='1' style='background-color: rgba(67,105,168,1)'></td>
+ <td width='1' style='background-color: rgba(4,35,88,1)'></td>
+ <td width='1' style='background-color: rgba(79,110,163,1)'></td>
+ <td width='1' style='background-color: rgba(108,139,192,1)'></td>
+ <td width='1' style='background-color: rgba(129,160,213,1)'></td>
+ <td width='1' style='background-color: rgba(147,178,231,1)'></td>
+ <td width='1' style='background-color: rgba(161,192,245,1)'></td>
+ <td width='1' style='background-color: rgba(161,192,245,1)'></td>
+ <td width='1' style='background-color: rgba(147,178,231,1)'></td>
+ <td width='1' style='background-color: rgba(129,160,213,1)'></td>
+ <td width='1' style='background-color: rgba(108,139,192,1)'></td>
+ <td width='1' style='background-color: rgba(79,110,163,1)'></td>
+ <td width='1' style='background-color: rgba(4,35,88,1)'></td>
+ <td width='1' style='background-color: rgba(67,105,168,1)'></td>
+ <td width='1' style='background-color: rgba(77,120,193,1)'></td>
+ <td width='1' style='background-color: rgba(76,126,208,1)'></td>
+ <td width='1' style='background-color: rgba(72,127,219,1)'></td>
+ <td width='1' style='background-color: rgba(65,126,228,1)'></td>
+ <td width='1' style='background-color: rgba(56,123,234,1)'></td>
+ <td width='1' style='background-color: rgba(45,118,239,1)'></td>
+ <td width='1' style='background-color: rgba(35,113,244,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(33,111,242,1)'></td>
+ <td width='1' style='background-color: rgba(43,116,237,1)'></td>
+ <td width='1' style='background-color: rgba(52,119,230,1)'></td>
+ <td width='1' style='background-color: rgba(59,120,222,1)'></td>
+ <td width='1' style='background-color: rgba(64,119,211,1)'></td>
+ <td width='1' style='background-color: rgba(64,114,196,1)'></td>
+ <td width='1' style='background-color: rgba(57,100,173,1)'></td>
+ <td width='1' style='background-color: rgba(4,42,105,1)'></td>
+ <td width='1' style='background-color: rgba(67,105,168,1)'></td>
+ <td width='1' style='background-color: rgba(90,128,191,1)'></td>
+ <td width='1' style='background-color: rgba(107,145,208,1)'></td>
+ <td width='1' style='background-color: rgba(122,160,223,1)'></td>
+ <td width='1' style='background-color: rgba(135,173,236,1)'></td>
+ <td width='1' style='background-color: rgba(146,184,247,1)'></td>
+ <td width='1' style='background-color: rgba(146,184,247,1)'></td>
+ <td width='1' style='background-color: rgba(135,173,236,1)'></td>
+ <td width='1' style='background-color: rgba(122,160,223,1)'></td>
+ <td width='1' style='background-color: rgba(107,145,208,1)'></td>
+ <td width='1' style='background-color: rgba(90,128,191,1)'></td>
+ <td width='1' style='background-color: rgba(67,105,168,1)'></td>
+ <td width='1' style='background-color: rgba(4,42,105,1)'></td>
+ <td width='1' style='background-color: rgba(57,100,173,1)'></td>
+ <td width='1' style='background-color: rgba(64,114,196,1)'></td>
+ <td width='1' style='background-color: rgba(64,119,211,1)'></td>
+ <td width='1' style='background-color: rgba(59,120,222,1)'></td>
+ <td width='1' style='background-color: rgba(52,119,230,1)'></td>
+ <td width='1' style='background-color: rgba(43,116,237,1)'></td>
+ <td width='1' style='background-color: rgba(33,111,242,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(20,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(31,109,240,1)'></td>
+ <td width='1' style='background-color: rgba(40,113,234,1)'></td>
+ <td width='1' style='background-color: rgba(47,114,225,1)'></td>
+ <td width='1' style='background-color: rgba(53,114,216,1)'></td>
+ <td width='1' style='background-color: rgba(54,109,201,1)'></td>
+ <td width='1' style='background-color: rgba(48,98,180,1)'></td>
+ <td width='1' style='background-color: rgba(5,48,121,1)'></td>
+ <td width='1' style='background-color: rgba(57,100,173,1)'></td>
+ <td width='1' style='background-color: rgba(77,120,193,1)'></td>
+ <td width='1' style='background-color: rgba(91,134,207,1)'></td>
+ <td width='1' style='background-color: rgba(104,147,220,1)'></td>
+ <td width='1' style='background-color: rgba(114,157,230,1)'></td>
+ <td width='1' style='background-color: rgba(124,167,240,1)'></td>
+ <td width='1' style='background-color: rgba(132,175,248,1)'></td>
+ <td width='1' style='background-color: rgba(132,175,248,1)'></td>
+ <td width='1' style='background-color: rgba(124,167,240,1)'></td>
+ <td width='1' style='background-color: rgba(114,157,230,1)'></td>
+ <td width='1' style='background-color: rgba(104,147,220,1)'></td>
+ <td width='1' style='background-color: rgba(91,134,207,1)'></td>
+ <td width='1' style='background-color: rgba(77,120,193,1)'></td>
+ <td width='1' style='background-color: rgba(57,100,173,1)'></td>
+ <td width='1' style='background-color: rgba(5,48,121,1)'></td>
+ <td width='1' style='background-color: rgba(48,98,180,1)'></td>
+ <td width='1' style='background-color: rgba(54,109,201,1)'></td>
+ <td width='1' style='background-color: rgba(53,114,216,1)'></td>
+ <td width='1' style='background-color: rgba(47,114,225,1)'></td>
+ <td width='1' style='background-color: rgba(40,113,234,1)'></td>
+ <td width='1' style='background-color: rgba(31,109,240,1)'></td>
+ <td width='1' style='background-color: rgba(20,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(19,104,244,1)'></td>
+ <td width='1' style='background-color: rgba(29,107,238,1)'></td>
+ <td width='1' style='background-color: rgba(37,110,231,1)'></td>
+ <td width='1' style='background-color: rgba(42,109,220,1)'></td>
+ <td width='1' style='background-color: rgba(45,106,208,1)'></td>
+ <td width='1' style='background-color: rgba(41,96,188,1)'></td>
+ <td width='1' style='background-color: rgba(5,55,137,1)'></td>
+ <td width='1' style='background-color: rgba(48,98,180,1)'></td>
+ <td width='1' style='background-color: rgba(64,114,196,1)'></td>
+ <td width='1' style='background-color: rgba(76,126,208,1)'></td>
+ <td width='1' style='background-color: rgba(86,136,218,1)'></td>
+ <td width='1' style='background-color: rgba(95,145,227,1)'></td>
+ <td width='1' style='background-color: rgba(103,153,235,1)'></td>
+ <td width='1' style='background-color: rgba(110,160,242,1)'></td>
+ <td width='1' style='background-color: rgba(116,166,248,1)'></td>
+ <td width='1' style='background-color: rgba(116,166,248,1)'></td>
+ <td width='1' style='background-color: rgba(110,160,242,1)'></td>
+ <td width='1' style='background-color: rgba(103,153,235,1)'></td>
+ <td width='1' style='background-color: rgba(95,145,227,1)'></td>
+ <td width='1' style='background-color: rgba(86,136,218,1)'></td>
+ <td width='1' style='background-color: rgba(76,126,208,1)'></td>
+ <td width='1' style='background-color: rgba(64,114,196,1)'></td>
+ <td width='1' style='background-color: rgba(48,98,180,1)'></td>
+ <td width='1' style='background-color: rgba(5,55,137,1)'></td>
+ <td width='1' style='background-color: rgba(41,96,188,1)'></td>
+ <td width='1' style='background-color: rgba(45,106,208,1)'></td>
+ <td width='1' style='background-color: rgba(42,109,220,1)'></td>
+ <td width='1' style='background-color: rgba(37,110,231,1)'></td>
+ <td width='1' style='background-color: rgba(29,107,238,1)'></td>
+ <td width='1' style='background-color: rgba(19,104,244,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(18,103,243,1)'></td>
+ <td width='1' style='background-color: rgba(28,106,237,1)'></td>
+ <td width='1' style='background-color: rgba(33,106,227,1)'></td>
+ <td width='1' style='background-color: rgba(36,103,214,1)'></td>
+ <td width='1' style='background-color: rgba(34,95,197,1)'></td>
+ <td width='1' style='background-color: rgba(6,61,153,1)'></td>
+ <td width='1' style='background-color: rgba(41,96,188,1)'></td>
+ <td width='1' style='background-color: rgba(54,109,201,1)'></td>
+ <td width='1' style='background-color: rgba(64,119,211,1)'></td>
+ <td width='1' style='background-color: rgba(72,127,219,1)'></td>
+ <td width='1' style='background-color: rgba(79,134,226,1)'></td>
+ <td width='1' style='background-color: rgba(86,141,233,1)'></td>
+ <td width='1' style='background-color: rgba(92,147,239,1)'></td>
+ <td width='1' style='background-color: rgba(97,152,244,1)'></td>
+ <td width='1' style='background-color: rgba(102,157,249,1)'></td>
+ <td width='1' style='background-color: rgba(102,157,249,1)'></td>
+ <td width='1' style='background-color: rgba(97,152,244,1)'></td>
+ <td width='1' style='background-color: rgba(92,147,239,1)'></td>
+ <td width='1' style='background-color: rgba(86,141,233,1)'></td>
+ <td width='1' style='background-color: rgba(79,134,226,1)'></td>
+ <td width='1' style='background-color: rgba(72,127,219,1)'></td>
+ <td width='1' style='background-color: rgba(64,119,211,1)'></td>
+ <td width='1' style='background-color: rgba(54,109,201,1)'></td>
+ <td width='1' style='background-color: rgba(41,96,188,1)'></td>
+ <td width='1' style='background-color: rgba(6,61,153,1)'></td>
+ <td width='1' style='background-color: rgba(34,95,197,1)'></td>
+ <td width='1' style='background-color: rgba(36,103,214,1)'></td>
+ <td width='1' style='background-color: rgba(33,106,227,1)'></td>
+ <td width='1' style='background-color: rgba(28,106,237,1)'></td>
+ <td width='1' style='background-color: rgba(18,103,243,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(17,102,242,1)'></td>
+ <td width='1' style='background-color: rgba(25,103,234,1)'></td>
+ <td width='1' style='background-color: rgba(29,102,223,1)'></td>
+ <td width='1' style='background-color: rgba(28,95,206,1)'></td>
+ <td width='1' style='background-color: rgba(7,68,170,1)'></td>
+ <td width='1' style='background-color: rgba(34,95,197,1)'></td>
+ <td width='1' style='background-color: rgba(45,106,208,1)'></td>
+ <td width='1' style='background-color: rgba(53,114,216,1)'></td>
+ <td width='1' style='background-color: rgba(59,120,222,1)'></td>
+ <td width='1' style='background-color: rgba(65,126,228,1)'></td>
+ <td width='1' style='background-color: rgba(70,131,233,1)'></td>
+ <td width='1' style='background-color: rgba(75,136,238,1)'></td>
+ <td width='1' style='background-color: rgba(79,140,242,1)'></td>
+ <td width='1' style='background-color: rgba(83,144,246,1)'></td>
+ <td width='1' style='background-color: rgba(87,148,250,1)'></td>
+ <td width='1' style='background-color: rgba(87,148,250,1)'></td>
+ <td width='1' style='background-color: rgba(83,144,246,1)'></td>
+ <td width='1' style='background-color: rgba(79,140,242,1)'></td>
+ <td width='1' style='background-color: rgba(75,136,238,1)'></td>
+ <td width='1' style='background-color: rgba(70,131,233,1)'></td>
+ <td width='1' style='background-color: rgba(65,126,228,1)'></td>
+ <td width='1' style='background-color: rgba(59,120,222,1)'></td>
+ <td width='1' style='background-color: rgba(53,114,216,1)'></td>
+ <td width='1' style='background-color: rgba(45,106,208,1)'></td>
+ <td width='1' style='background-color: rgba(34,95,197,1)'></td>
+ <td width='1' style='background-color: rgba(7,68,170,1)'></td>
+ <td width='1' style='background-color: rgba(28,95,206,1)'></td>
+ <td width='1' style='background-color: rgba(29,102,223,1)'></td>
+ <td width='1' style='background-color: rgba(25,103,234,1)'></td>
+ <td width='1' style='background-color: rgba(17,102,242,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(16,101,241,1)'></td>
+ <td width='1' style='background-color: rgba(22,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(23,96,217,1)'></td>
+ <td width='1' style='background-color: rgba(7,74,185,1)'></td>
+ <td width='1' style='background-color: rgba(28,95,206,1)'></td>
+ <td width='1' style='background-color: rgba(36,103,214,1)'></td>
+ <td width='1' style='background-color: rgba(42,109,220,1)'></td>
+ <td width='1' style='background-color: rgba(47,114,225,1)'></td>
+ <td width='1' style='background-color: rgba(52,119,230,1)'></td>
+ <td width='1' style='background-color: rgba(56,123,234,1)'></td>
+ <td width='1' style='background-color: rgba(59,126,237,1)'></td>
+ <td width='1' style='background-color: rgba(62,129,240,1)'></td>
+ <td width='1' style='background-color: rgba(66,133,244,1)'></td>
+ <td width='1' style='background-color: rgba(68,135,246,1)'></td>
+ <td width='1' style='background-color: rgba(71,138,249,1)'></td>
+ <td width='1' style='background-color: rgba(71,138,249,1)'></td>
+ <td width='1' style='background-color: rgba(68,135,246,1)'></td>
+ <td width='1' style='background-color: rgba(66,133,244,1)'></td>
+ <td width='1' style='background-color: rgba(62,129,240,1)'></td>
+ <td width='1' style='background-color: rgba(59,126,237,1)'></td>
+ <td width='1' style='background-color: rgba(56,123,234,1)'></td>
+ <td width='1' style='background-color: rgba(52,119,230,1)'></td>
+ <td width='1' style='background-color: rgba(47,114,225,1)'></td>
+ <td width='1' style='background-color: rgba(42,109,220,1)'></td>
+ <td width='1' style='background-color: rgba(36,103,214,1)'></td>
+ <td width='1' style='background-color: rgba(28,95,206,1)'></td>
+ <td width='1' style='background-color: rgba(7,74,185,1)'></td>
+ <td width='1' style='background-color: rgba(23,96,217,1)'></td>
+ <td width='1' style='background-color: rgba(22,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(16,101,241,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(15,100,240,1)'></td>
+ <td width='1' style='background-color: rgba(19,97,228,1)'></td>
+ <td width='1' style='background-color: rgba(8,81,202,1)'></td>
+ <td width='1' style='background-color: rgba(23,96,217,1)'></td>
+ <td width='1' style='background-color: rgba(29,102,223,1)'></td>
+ <td width='1' style='background-color: rgba(33,106,227,1)'></td>
+ <td width='1' style='background-color: rgba(37,110,231,1)'></td>
+ <td width='1' style='background-color: rgba(40,113,234,1)'></td>
+ <td width='1' style='background-color: rgba(43,116,237,1)'></td>
+ <td width='1' style='background-color: rgba(45,118,239,1)'></td>
+ <td width='1' style='background-color: rgba(47,120,241,1)'></td>
+ <td width='1' style='background-color: rgba(50,123,244,1)'></td>
+ <td width='1' style='background-color: rgba(52,125,246,1)'></td>
+ <td width='1' style='background-color: rgba(54,127,248,1)'></td>
+ <td width='1' style='background-color: rgba(56,129,250,1)'></td>
+ <td width='1' style='background-color: rgba(56,129,250,1)'></td>
+ <td width='1' style='background-color: rgba(54,127,248,1)'></td>
+ <td width='1' style='background-color: rgba(52,125,246,1)'></td>
+ <td width='1' style='background-color: rgba(50,123,244,1)'></td>
+ <td width='1' style='background-color: rgba(47,120,241,1)'></td>
+ <td width='1' style='background-color: rgba(45,118,239,1)'></td>
+ <td width='1' style='background-color: rgba(43,116,237,1)'></td>
+ <td width='1' style='background-color: rgba(40,113,234,1)'></td>
+ <td width='1' style='background-color: rgba(37,110,231,1)'></td>
+ <td width='1' style='background-color: rgba(33,106,227,1)'></td>
+ <td width='1' style='background-color: rgba(29,102,223,1)'></td>
+ <td width='1' style='background-color: rgba(23,96,217,1)'></td>
+ <td width='1' style='background-color: rgba(8,81,202,1)'></td>
+ <td width='1' style='background-color: rgba(19,97,228,1)'></td>
+ <td width='1' style='background-color: rgba(15,100,240,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(13,98,238,1)'></td>
+ <td width='1' style='background-color: rgba(9,87,218,1)'></td>
+ <td width='1' style='background-color: rgba(19,97,228,1)'></td>
+ <td width='1' style='background-color: rgba(22,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(25,103,234,1)'></td>
+ <td width='1' style='background-color: rgba(28,106,237,1)'></td>
+ <td width='1' style='background-color: rgba(29,107,238,1)'></td>
+ <td width='1' style='background-color: rgba(31,109,240,1)'></td>
+ <td width='1' style='background-color: rgba(33,111,242,1)'></td>
+ <td width='1' style='background-color: rgba(35,113,244,1)'></td>
+ <td width='1' style='background-color: rgba(36,114,245,1)'></td>
+ <td width='1' style='background-color: rgba(37,115,246,1)'></td>
+ <td width='1' style='background-color: rgba(39,117,248,1)'></td>
+ <td width='1' style='background-color: rgba(40,118,249,1)'></td>
+ <td width='1' style='background-color: rgba(41,119,250,1)'></td>
+ <td width='1' style='background-color: rgba(41,119,250,1)'></td>
+ <td width='1' style='background-color: rgba(40,118,249,1)'></td>
+ <td width='1' style='background-color: rgba(39,117,248,1)'></td>
+ <td width='1' style='background-color: rgba(37,115,246,1)'></td>
+ <td width='1' style='background-color: rgba(36,114,245,1)'></td>
+ <td width='1' style='background-color: rgba(35,113,244,1)'></td>
+ <td width='1' style='background-color: rgba(33,111,242,1)'></td>
+ <td width='1' style='background-color: rgba(31,109,240,1)'></td>
+ <td width='1' style='background-color: rgba(29,107,238,1)'></td>
+ <td width='1' style='background-color: rgba(28,106,237,1)'></td>
+ <td width='1' style='background-color: rgba(25,103,234,1)'></td>
+ <td width='1' style='background-color: rgba(22,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(19,97,228,1)'></td>
+ <td width='1' style='background-color: rgba(9,87,218,1)'></td>
+ <td width='1' style='background-color: rgba(13,98,238,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,94,234,1)'></td>
+ <td width='1' style='background-color: rgba(13,98,238,1)'></td>
+ <td width='1' style='background-color: rgba(15,100,240,1)'></td>
+ <td width='1' style='background-color: rgba(16,101,241,1)'></td>
+ <td width='1' style='background-color: rgba(17,102,242,1)'></td>
+ <td width='1' style='background-color: rgba(18,103,243,1)'></td>
+ <td width='1' style='background-color: rgba(19,104,244,1)'></td>
+ <td width='1' style='background-color: rgba(20,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(22,107,247,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(24,109,249,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(23,108,248,1)'></td>
+ <td width='1' style='background-color: rgba(22,107,247,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(21,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(20,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(19,104,244,1)'></td>
+ <td width='1' style='background-color: rgba(18,103,243,1)'></td>
+ <td width='1' style='background-color: rgba(17,102,242,1)'></td>
+ <td width='1' style='background-color: rgba(16,101,241,1)'></td>
+ <td width='1' style='background-color: rgba(15,100,240,1)'></td>
+ <td width='1' style='background-color: rgba(13,98,238,1)'></td>
+ <td width='1' style='background-color: rgba(9,94,234,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-background/bg__6a08.html b/image/test/reftest/pngsuite-background/bg__6a08.html
new file mode 100644
index 0000000000..1ab2721f31
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/bg__6a08.html
@@ -0,0 +1,1092 @@
+<html><body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(18,97,243,1)'></td>
+ <td width='1' style='background-color: rgba(25,94,237,1)'></td>
+ <td width='1' style='background-color: rgba(33,91,230,1)'></td>
+ <td width='1' style='background-color: rgba(41,87,225,1)'></td>
+ <td width='1' style='background-color: rgba(49,84,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,81,212,1)'></td>
+ <td width='1' style='background-color: rgba(65,78,205,1)'></td>
+ <td width='1' style='background-color: rgba(72,75,199,1)'></td>
+ <td width='1' style='background-color: rgba(81,71,192,1)'></td>
+ <td width='1' style='background-color: rgba(89,68,187,1)'></td>
+ <td width='1' style='background-color: rgba(96,65,180,1)'></td>
+ <td width='1' style='background-color: rgba(104,62,174,1)'></td>
+ <td width='1' style='background-color: rgba(112,58,168,1)'></td>
+ <td width='1' style='background-color: rgba(120,55,160,1)'></td>
+ <td width='1' style='background-color: rgba(128,52,154,1)'></td>
+ <td width='1' style='background-color: rgba(136,49,149,1)'></td>
+ <td width='1' style='background-color: rgba(144,45,142,1)'></td>
+ <td width='1' style='background-color: rgba(152,42,135,1)'></td>
+ <td width='1' style='background-color: rgba(160,39,129,1)'></td>
+ <td width='1' style='background-color: rgba(168,36,123,1)'></td>
+ <td width='1' style='background-color: rgba(175,33,116,1)'></td>
+ <td width='1' style='background-color: rgba(183,29,111,1)'></td>
+ <td width='1' style='background-color: rgba(192,26,104,1)'></td>
+ <td width='1' style='background-color: rgba(199,23,97,1)'></td>
+ <td width='1' style='background-color: rgba(207,20,91,1)'></td>
+ <td width='1' style='background-color: rgba(215,16,85,1)'></td>
+ <td width='1' style='background-color: rgba(223,13,78,1)'></td>
+ <td width='1' style='background-color: rgba(231,10,72,1)'></td>
+ <td width='1' style='background-color: rgba(239,7,66,1)'></td>
+ <td width='1' style='background-color: rgba(246,4,60,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,53,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(18,100,243,1)'></td>
+ <td width='1' style='background-color: rgba(25,100,237,1)'></td>
+ <td width='1' style='background-color: rgba(33,100,230,1)'></td>
+ <td width='1' style='background-color: rgba(41,99,225,1)'></td>
+ <td width='1' style='background-color: rgba(49,99,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,99,212,1)'></td>
+ <td width='1' style='background-color: rgba(65,99,205,1)'></td>
+ <td width='1' style='background-color: rgba(72,99,199,1)'></td>
+ <td width='1' style='background-color: rgba(81,99,192,1)'></td>
+ <td width='1' style='background-color: rgba(89,99,187,1)'></td>
+ <td width='1' style='background-color: rgba(96,99,180,1)'></td>
+ <td width='1' style='background-color: rgba(104,99,174,1)'></td>
+ <td width='1' style='background-color: rgba(112,98,168,1)'></td>
+ <td width='1' style='background-color: rgba(120,99,160,1)'></td>
+ <td width='1' style='background-color: rgba(128,99,154,1)'></td>
+ <td width='1' style='background-color: rgba(136,99,149,1)'></td>
+ <td width='1' style='background-color: rgba(144,98,142,1)'></td>
+ <td width='1' style='background-color: rgba(152,98,135,1)'></td>
+ <td width='1' style='background-color: rgba(160,98,129,1)'></td>
+ <td width='1' style='background-color: rgba(168,99,123,1)'></td>
+ <td width='1' style='background-color: rgba(175,99,116,1)'></td>
+ <td width='1' style='background-color: rgba(183,98,111,1)'></td>
+ <td width='1' style='background-color: rgba(192,98,104,1)'></td>
+ <td width='1' style='background-color: rgba(199,98,97,1)'></td>
+ <td width='1' style='background-color: rgba(207,98,91,1)'></td>
+ <td width='1' style='background-color: rgba(215,97,85,1)'></td>
+ <td width='1' style='background-color: rgba(223,98,78,1)'></td>
+ <td width='1' style='background-color: rgba(231,98,72,1)'></td>
+ <td width='1' style='background-color: rgba(239,98,66,1)'></td>
+ <td width='1' style='background-color: rgba(246,98,60,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,53,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(18,101,243,1)'></td>
+ <td width='1' style='background-color: rgba(25,102,237,1)'></td>
+ <td width='1' style='background-color: rgba(33,103,230,1)'></td>
+ <td width='1' style='background-color: rgba(41,103,225,1)'></td>
+ <td width='1' style='background-color: rgba(49,105,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,106,212,1)'></td>
+ <td width='1' style='background-color: rgba(65,108,205,1)'></td>
+ <td width='1' style='background-color: rgba(72,109,199,1)'></td>
+ <td width='1' style='background-color: rgba(81,110,192,1)'></td>
+ <td width='1' style='background-color: rgba(89,111,187,1)'></td>
+ <td width='1' style='background-color: rgba(96,112,180,1)'></td>
+ <td width='1' style='background-color: rgba(104,113,174,1)'></td>
+ <td width='1' style='background-color: rgba(112,114,168,1)'></td>
+ <td width='1' style='background-color: rgba(120,115,160,1)'></td>
+ <td width='1' style='background-color: rgba(128,117,154,1)'></td>
+ <td width='1' style='background-color: rgba(136,118,149,1)'></td>
+ <td width='1' style='background-color: rgba(144,118,142,1)'></td>
+ <td width='1' style='background-color: rgba(152,120,135,1)'></td>
+ <td width='1' style='background-color: rgba(160,121,129,1)'></td>
+ <td width='1' style='background-color: rgba(168,122,123,1)'></td>
+ <td width='1' style='background-color: rgba(175,124,116,1)'></td>
+ <td width='1' style='background-color: rgba(183,124,111,1)'></td>
+ <td width='1' style='background-color: rgba(192,126,104,1)'></td>
+ <td width='1' style='background-color: rgba(199,127,97,1)'></td>
+ <td width='1' style='background-color: rgba(207,128,91,1)'></td>
+ <td width='1' style='background-color: rgba(215,128,85,1)'></td>
+ <td width='1' style='background-color: rgba(223,130,78,1)'></td>
+ <td width='1' style='background-color: rgba(231,131,72,1)'></td>
+ <td width='1' style='background-color: rgba(239,133,66,1)'></td>
+ <td width='1' style='background-color: rgba(246,134,60,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,53,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(18,102,243,1)'></td>
+ <td width='1' style='background-color: rgba(25,104,237,1)'></td>
+ <td width='1' style='background-color: rgba(33,106,230,1)'></td>
+ <td width='1' style='background-color: rgba(41,107,225,1)'></td>
+ <td width='1' style='background-color: rgba(49,110,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,112,212,1)'></td>
+ <td width='1' style='background-color: rgba(65,114,205,1)'></td>
+ <td width='1' style='background-color: rgba(72,116,199,1)'></td>
+ <td width='1' style='background-color: rgba(81,118,192,1)'></td>
+ <td width='1' style='background-color: rgba(89,120,187,1)'></td>
+ <td width='1' style='background-color: rgba(96,122,180,1)'></td>
+ <td width='1' style='background-color: rgba(104,124,174,1)'></td>
+ <td width='1' style='background-color: rgba(112,125,168,1)'></td>
+ <td width='1' style='background-color: rgba(120,128,160,1)'></td>
+ <td width='1' style='background-color: rgba(128,130,154,1)'></td>
+ <td width='1' style='background-color: rgba(136,132,149,1)'></td>
+ <td width='1' style='background-color: rgba(144,133,142,1)'></td>
+ <td width='1' style='background-color: rgba(152,136,135,1)'></td>
+ <td width='1' style='background-color: rgba(160,138,129,1)'></td>
+ <td width='1' style='background-color: rgba(168,140,123,1)'></td>
+ <td width='1' style='background-color: rgba(175,142,116,1)'></td>
+ <td width='1' style='background-color: rgba(183,144,111,1)'></td>
+ <td width='1' style='background-color: rgba(192,146,104,1)'></td>
+ <td width='1' style='background-color: rgba(199,148,97,1)'></td>
+ <td width='1' style='background-color: rgba(207,151,91,1)'></td>
+ <td width='1' style='background-color: rgba(215,152,85,1)'></td>
+ <td width='1' style='background-color: rgba(223,154,78,1)'></td>
+ <td width='1' style='background-color: rgba(231,157,72,1)'></td>
+ <td width='1' style='background-color: rgba(239,159,66,1)'></td>
+ <td width='1' style='background-color: rgba(246,161,60,1)'></td>
+ <td width='1' style='background-color: rgba(255,163,53,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(18,102,243,1)'></td>
+ <td width='1' style='background-color: rgba(25,105,237,1)'></td>
+ <td width='1' style='background-color: rgba(33,108,230,1)'></td>
+ <td width='1' style='background-color: rgba(41,110,225,1)'></td>
+ <td width='1' style='background-color: rgba(49,113,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,116,211,1)'></td>
+ <td width='1' style='background-color: rgba(65,119,205,1)'></td>
+ <td width='1' style='background-color: rgba(72,122,198,1)'></td>
+ <td width='1' style='background-color: rgba(81,124,191,1)'></td>
+ <td width='1' style='background-color: rgba(89,127,186,1)'></td>
+ <td width='1' style='background-color: rgba(96,130,179,1)'></td>
+ <td width='1' style='background-color: rgba(104,133,173,1)'></td>
+ <td width='1' style='background-color: rgba(112,135,166,1)'></td>
+ <td width='1' style='background-color: rgba(120,138,159,1)'></td>
+ <td width='1' style='background-color: rgba(128,141,153,1)'></td>
+ <td width='1' style='background-color: rgba(136,144,147,1)'></td>
+ <td width='1' style='background-color: rgba(144,146,141,1)'></td>
+ <td width='1' style='background-color: rgba(152,149,134,1)'></td>
+ <td width='1' style='background-color: rgba(160,152,127,1)'></td>
+ <td width='1' style='background-color: rgba(168,155,121,1)'></td>
+ <td width='1' style='background-color: rgba(175,158,114,1)'></td>
+ <td width='1' style='background-color: rgba(183,160,109,1)'></td>
+ <td width='1' style='background-color: rgba(192,163,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,166,95,1)'></td>
+ <td width='1' style='background-color: rgba(207,169,89,1)'></td>
+ <td width='1' style='background-color: rgba(215,171,82,1)'></td>
+ <td width='1' style='background-color: rgba(223,174,75,1)'></td>
+ <td width='1' style='background-color: rgba(231,177,70,1)'></td>
+ <td width='1' style='background-color: rgba(239,180,63,1)'></td>
+ <td width='1' style='background-color: rgba(246,183,57,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,50,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(18,103,243,1)'></td>
+ <td width='1' style='background-color: rgba(25,106,237,1)'></td>
+ <td width='1' style='background-color: rgba(33,110,230,1)'></td>
+ <td width='1' style='background-color: rgba(41,112,225,1)'></td>
+ <td width='1' style='background-color: rgba(49,117,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,120,211,1)'></td>
+ <td width='1' style='background-color: rgba(65,124,205,1)'></td>
+ <td width='1' style='background-color: rgba(72,127,198,1)'></td>
+ <td width='1' style='background-color: rgba(81,130,191,1)'></td>
+ <td width='1' style='background-color: rgba(89,134,186,1)'></td>
+ <td width='1' style='background-color: rgba(96,137,179,1)'></td>
+ <td width='1' style='background-color: rgba(104,141,173,1)'></td>
+ <td width='1' style='background-color: rgba(112,143,166,1)'></td>
+ <td width='1' style='background-color: rgba(120,147,159,1)'></td>
+ <td width='1' style='background-color: rgba(128,151,153,1)'></td>
+ <td width='1' style='background-color: rgba(136,154,147,1)'></td>
+ <td width='1' style='background-color: rgba(144,157,141,1)'></td>
+ <td width='1' style='background-color: rgba(152,161,134,1)'></td>
+ <td width='1' style='background-color: rgba(160,165,127,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,121,1)'></td>
+ <td width='1' style='background-color: rgba(175,171,114,1)'></td>
+ <td width='1' style='background-color: rgba(183,174,109,1)'></td>
+ <td width='1' style='background-color: rgba(192,178,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,182,95,1)'></td>
+ <td width='1' style='background-color: rgba(207,185,89,1)'></td>
+ <td width='1' style='background-color: rgba(215,188,82,1)'></td>
+ <td width='1' style='background-color: rgba(223,192,75,1)'></td>
+ <td width='1' style='background-color: rgba(231,195,70,1)'></td>
+ <td width='1' style='background-color: rgba(239,199,63,1)'></td>
+ <td width='1' style='background-color: rgba(246,202,57,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,50,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(18,104,243,1)'></td>
+ <td width='1' style='background-color: rgba(25,108,237,1)'></td>
+ <td width='1' style='background-color: rgba(33,112,230,1)'></td>
+ <td width='1' style='background-color: rgba(41,115,225,1)'></td>
+ <td width='1' style='background-color: rgba(49,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,124,211,1)'></td>
+ <td width='1' style='background-color: rgba(65,128,205,1)'></td>
+ <td width='1' style='background-color: rgba(72,132,198,1)'></td>
+ <td width='1' style='background-color: rgba(81,136,191,1)'></td>
+ <td width='1' style='background-color: rgba(89,140,186,1)'></td>
+ <td width='1' style='background-color: rgba(96,144,179,1)'></td>
+ <td width='1' style='background-color: rgba(104,148,173,1)'></td>
+ <td width='1' style='background-color: rgba(112,151,166,1)'></td>
+ <td width='1' style='background-color: rgba(120,156,159,1)'></td>
+ <td width='1' style='background-color: rgba(128,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(136,164,147,1)'></td>
+ <td width='1' style='background-color: rgba(144,167,141,1)'></td>
+ <td width='1' style='background-color: rgba(152,172,134,1)'></td>
+ <td width='1' style='background-color: rgba(160,176,127,1)'></td>
+ <td width='1' style='background-color: rgba(168,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(175,184,114,1)'></td>
+ <td width='1' style='background-color: rgba(183,187,109,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,196,95,1)'></td>
+ <td width='1' style='background-color: rgba(207,200,89,1)'></td>
+ <td width='1' style='background-color: rgba(215,203,82,1)'></td>
+ <td width='1' style='background-color: rgba(223,208,75,1)'></td>
+ <td width='1' style='background-color: rgba(231,212,70,1)'></td>
+ <td width='1' style='background-color: rgba(239,216,63,1)'></td>
+ <td width='1' style='background-color: rgba(246,220,57,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,50,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(18,104,243,1)'></td>
+ <td width='1' style='background-color: rgba(25,109,237,1)'></td>
+ <td width='1' style='background-color: rgba(33,113,230,1)'></td>
+ <td width='1' style='background-color: rgba(41,117,225,1)'></td>
+ <td width='1' style='background-color: rgba(49,122,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,127,211,1)'></td>
+ <td width='1' style='background-color: rgba(65,131,205,1)'></td>
+ <td width='1' style='background-color: rgba(72,136,198,1)'></td>
+ <td width='1' style='background-color: rgba(81,140,191,1)'></td>
+ <td width='1' style='background-color: rgba(89,145,186,1)'></td>
+ <td width='1' style='background-color: rgba(96,149,179,1)'></td>
+ <td width='1' style='background-color: rgba(104,154,173,1)'></td>
+ <td width='1' style='background-color: rgba(112,157,166,1)'></td>
+ <td width='1' style='background-color: rgba(120,163,159,1)'></td>
+ <td width='1' style='background-color: rgba(128,167,153,1)'></td>
+ <td width='1' style='background-color: rgba(136,172,147,1)'></td>
+ <td width='1' style='background-color: rgba(144,175,141,1)'></td>
+ <td width='1' style='background-color: rgba(152,181,134,1)'></td>
+ <td width='1' style='background-color: rgba(160,185,127,1)'></td>
+ <td width='1' style='background-color: rgba(168,190,121,1)'></td>
+ <td width='1' style='background-color: rgba(175,194,114,1)'></td>
+ <td width='1' style='background-color: rgba(183,198,109,1)'></td>
+ <td width='1' style='background-color: rgba(192,203,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,208,95,1)'></td>
+ <td width='1' style='background-color: rgba(207,212,89,1)'></td>
+ <td width='1' style='background-color: rgba(215,216,82,1)'></td>
+ <td width='1' style='background-color: rgba(223,221,75,1)'></td>
+ <td width='1' style='background-color: rgba(231,226,70,1)'></td>
+ <td width='1' style='background-color: rgba(239,231,63,1)'></td>
+ <td width='1' style='background-color: rgba(246,235,57,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,50,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(18,105,243,1)'></td>
+ <td width='1' style='background-color: rgba(25,110,236,1)'></td>
+ <td width='1' style='background-color: rgba(33,115,230,1)'></td>
+ <td width='1' style='background-color: rgba(41,119,224,1)'></td>
+ <td width='1' style='background-color: rgba(49,125,217,1)'></td>
+ <td width='1' style='background-color: rgba(57,130,210,1)'></td>
+ <td width='1' style='background-color: rgba(65,135,204,1)'></td>
+ <td width='1' style='background-color: rgba(72,140,197,1)'></td>
+ <td width='1' style='background-color: rgba(81,145,190,1)'></td>
+ <td width='1' style='background-color: rgba(89,150,184,1)'></td>
+ <td width='1' style='background-color: rgba(96,155,178,1)'></td>
+ <td width='1' style='background-color: rgba(104,160,171,1)'></td>
+ <td width='1' style='background-color: rgba(112,164,165,1)'></td>
+ <td width='1' style='background-color: rgba(120,170,157,1)'></td>
+ <td width='1' style='background-color: rgba(128,175,151,1)'></td>
+ <td width='1' style='background-color: rgba(136,180,145,1)'></td>
+ <td width='1' style='background-color: rgba(144,184,139,1)'></td>
+ <td width='1' style='background-color: rgba(152,190,131,1)'></td>
+ <td width='1' style='background-color: rgba(160,195,125,1)'></td>
+ <td width='1' style='background-color: rgba(168,200,118,1)'></td>
+ <td width='1' style='background-color: rgba(175,205,112,1)'></td>
+ <td width='1' style='background-color: rgba(183,209,106,1)'></td>
+ <td width='1' style='background-color: rgba(192,215,99,1)'></td>
+ <td width='1' style='background-color: rgba(199,220,92,1)'></td>
+ <td width='1' style='background-color: rgba(207,225,85,1)'></td>
+ <td width='1' style='background-color: rgba(215,229,79,1)'></td>
+ <td width='1' style='background-color: rgba(223,235,72,1)'></td>
+ <td width='1' style='background-color: rgba(231,240,66,1)'></td>
+ <td width='1' style='background-color: rgba(239,245,59,1)'></td>
+ <td width='1' style='background-color: rgba(246,250,53,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,46,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(17,105,243,1)'></td>
+ <td width='1' style='background-color: rgba(24,110,236,1)'></td>
+ <td width='1' style='background-color: rgba(31,115,230,1)'></td>
+ <td width='1' style='background-color: rgba(39,119,224,1)'></td>
+ <td width='1' style='background-color: rgba(46,125,217,1)'></td>
+ <td width='1' style='background-color: rgba(54,130,210,1)'></td>
+ <td width='1' style='background-color: rgba(61,135,204,1)'></td>
+ <td width='1' style='background-color: rgba(68,140,197,1)'></td>
+ <td width='1' style='background-color: rgba(76,145,190,1)'></td>
+ <td width='1' style='background-color: rgba(84,150,184,1)'></td>
+ <td width='1' style='background-color: rgba(90,155,178,1)'></td>
+ <td width='1' style='background-color: rgba(98,160,171,1)'></td>
+ <td width='1' style='background-color: rgba(105,164,165,1)'></td>
+ <td width='1' style='background-color: rgba(113,170,157,1)'></td>
+ <td width='1' style='background-color: rgba(120,175,151,1)'></td>
+ <td width='1' style='background-color: rgba(128,180,145,1)'></td>
+ <td width='1' style='background-color: rgba(135,184,139,1)'></td>
+ <td width='1' style='background-color: rgba(143,190,131,1)'></td>
+ <td width='1' style='background-color: rgba(150,195,125,1)'></td>
+ <td width='1' style='background-color: rgba(158,200,118,1)'></td>
+ <td width='1' style='background-color: rgba(164,205,112,1)'></td>
+ <td width='1' style='background-color: rgba(172,209,106,1)'></td>
+ <td width='1' style='background-color: rgba(180,215,99,1)'></td>
+ <td width='1' style='background-color: rgba(187,220,92,1)'></td>
+ <td width='1' style='background-color: rgba(194,225,85,1)'></td>
+ <td width='1' style='background-color: rgba(202,229,79,1)'></td>
+ <td width='1' style='background-color: rgba(209,235,72,1)'></td>
+ <td width='1' style='background-color: rgba(217,240,66,1)'></td>
+ <td width='1' style='background-color: rgba(225,245,59,1)'></td>
+ <td width='1' style='background-color: rgba(231,250,53,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,46,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(17,105,243,1)'></td>
+ <td width='1' style='background-color: rgba(23,110,236,1)'></td>
+ <td width='1' style='background-color: rgba(30,115,230,1)'></td>
+ <td width='1' style='background-color: rgba(37,119,224,1)'></td>
+ <td width='1' style='background-color: rgba(44,125,217,1)'></td>
+ <td width='1' style='background-color: rgba(51,130,210,1)'></td>
+ <td width='1' style='background-color: rgba(58,135,204,1)'></td>
+ <td width='1' style='background-color: rgba(64,140,197,1)'></td>
+ <td width='1' style='background-color: rgba(72,145,190,1)'></td>
+ <td width='1' style='background-color: rgba(79,150,184,1)'></td>
+ <td width='1' style='background-color: rgba(85,155,178,1)'></td>
+ <td width='1' style='background-color: rgba(92,160,171,1)'></td>
+ <td width='1' style='background-color: rgba(99,164,165,1)'></td>
+ <td width='1' style='background-color: rgba(106,170,157,1)'></td>
+ <td width='1' style='background-color: rgba(113,175,151,1)'></td>
+ <td width='1' style='background-color: rgba(120,180,145,1)'></td>
+ <td width='1' style='background-color: rgba(127,184,139,1)'></td>
+ <td width='1' style='background-color: rgba(134,190,131,1)'></td>
+ <td width='1' style='background-color: rgba(141,195,125,1)'></td>
+ <td width='1' style='background-color: rgba(148,200,118,1)'></td>
+ <td width='1' style='background-color: rgba(154,205,112,1)'></td>
+ <td width='1' style='background-color: rgba(161,209,106,1)'></td>
+ <td width='1' style='background-color: rgba(169,215,99,1)'></td>
+ <td width='1' style='background-color: rgba(175,220,92,1)'></td>
+ <td width='1' style='background-color: rgba(182,225,85,1)'></td>
+ <td width='1' style='background-color: rgba(189,229,79,1)'></td>
+ <td width='1' style='background-color: rgba(196,235,72,1)'></td>
+ <td width='1' style='background-color: rgba(203,240,66,1)'></td>
+ <td width='1' style='background-color: rgba(210,245,59,1)'></td>
+ <td width='1' style='background-color: rgba(216,250,53,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,46,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(16,105,243,1)'></td>
+ <td width='1' style='background-color: rgba(21,110,236,1)'></td>
+ <td width='1' style='background-color: rgba(28,115,230,1)'></td>
+ <td width='1' style='background-color: rgba(34,119,224,1)'></td>
+ <td width='1' style='background-color: rgba(41,125,216,1)'></td>
+ <td width='1' style='background-color: rgba(47,130,210,1)'></td>
+ <td width='1' style='background-color: rgba(54,135,203,1)'></td>
+ <td width='1' style='background-color: rgba(59,140,196,1)'></td>
+ <td width='1' style='background-color: rgba(66,145,189,1)'></td>
+ <td width='1' style='background-color: rgba(73,150,183,1)'></td>
+ <td width='1' style='background-color: rgba(78,155,177,1)'></td>
+ <td width='1' style='background-color: rgba(85,160,170,1)'></td>
+ <td width='1' style='background-color: rgba(91,164,163,1)'></td>
+ <td width='1' style='background-color: rgba(97,170,156,1)'></td>
+ <td width='1' style='background-color: rgba(104,175,149,1)'></td>
+ <td width='1' style='background-color: rgba(110,180,144,1)'></td>
+ <td width='1' style='background-color: rgba(117,184,137,1)'></td>
+ <td width='1' style='background-color: rgba(123,190,129,1)'></td>
+ <td width='1' style='background-color: rgba(130,195,123,1)'></td>
+ <td width='1' style='background-color: rgba(136,200,116,1)'></td>
+ <td width='1' style='background-color: rgba(141,205,110,1)'></td>
+ <td width='1' style='background-color: rgba(148,209,104,1)'></td>
+ <td width='1' style='background-color: rgba(155,215,96,1)'></td>
+ <td width='1' style='background-color: rgba(161,220,90,1)'></td>
+ <td width='1' style='background-color: rgba(167,225,83,1)'></td>
+ <td width='1' style='background-color: rgba(174,229,76,1)'></td>
+ <td width='1' style='background-color: rgba(180,235,69,1)'></td>
+ <td width='1' style='background-color: rgba(186,240,63,1)'></td>
+ <td width='1' style='background-color: rgba(193,245,57,1)'></td>
+ <td width='1' style='background-color: rgba(198,250,50,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,43,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(15,105,243,1)'></td>
+ <td width='1' style='background-color: rgba(20,110,236,1)'></td>
+ <td width='1' style='background-color: rgba(26,115,230,1)'></td>
+ <td width='1' style='background-color: rgba(32,119,224,1)'></td>
+ <td width='1' style='background-color: rgba(37,125,216,1)'></td>
+ <td width='1' style='background-color: rgba(43,130,210,1)'></td>
+ <td width='1' style='background-color: rgba(49,135,203,1)'></td>
+ <td width='1' style='background-color: rgba(54,140,196,1)'></td>
+ <td width='1' style='background-color: rgba(60,145,189,1)'></td>
+ <td width='1' style='background-color: rgba(66,150,183,1)'></td>
+ <td width='1' style='background-color: rgba(71,155,177,1)'></td>
+ <td width='1' style='background-color: rgba(77,160,170,1)'></td>
+ <td width='1' style='background-color: rgba(83,164,163,1)'></td>
+ <td width='1' style='background-color: rgba(88,170,156,1)'></td>
+ <td width='1' style='background-color: rgba(94,175,149,1)'></td>
+ <td width='1' style='background-color: rgba(100,180,144,1)'></td>
+ <td width='1' style='background-color: rgba(106,184,137,1)'></td>
+ <td width='1' style='background-color: rgba(111,190,129,1)'></td>
+ <td width='1' style='background-color: rgba(117,195,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,200,116,1)'></td>
+ <td width='1' style='background-color: rgba(128,205,110,1)'></td>
+ <td width='1' style='background-color: rgba(134,209,104,1)'></td>
+ <td width='1' style='background-color: rgba(140,215,96,1)'></td>
+ <td width='1' style='background-color: rgba(145,220,90,1)'></td>
+ <td width='1' style='background-color: rgba(151,225,83,1)'></td>
+ <td width='1' style='background-color: rgba(157,229,76,1)'></td>
+ <td width='1' style='background-color: rgba(162,235,69,1)'></td>
+ <td width='1' style='background-color: rgba(168,240,63,1)'></td>
+ <td width='1' style='background-color: rgba(174,245,57,1)'></td>
+ <td width='1' style='background-color: rgba(179,250,50,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,43,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(15,105,243,1)'></td>
+ <td width='1' style='background-color: rgba(19,110,236,1)'></td>
+ <td width='1' style='background-color: rgba(24,115,230,1)'></td>
+ <td width='1' style='background-color: rgba(29,119,224,1)'></td>
+ <td width='1' style='background-color: rgba(34,125,216,1)'></td>
+ <td width='1' style='background-color: rgba(39,130,210,1)'></td>
+ <td width='1' style='background-color: rgba(44,135,203,1)'></td>
+ <td width='1' style='background-color: rgba(48,140,196,1)'></td>
+ <td width='1' style='background-color: rgba(54,145,189,1)'></td>
+ <td width='1' style='background-color: rgba(59,150,183,1)'></td>
+ <td width='1' style='background-color: rgba(63,155,177,1)'></td>
+ <td width='1' style='background-color: rgba(69,160,170,1)'></td>
+ <td width='1' style='background-color: rgba(74,164,163,1)'></td>
+ <td width='1' style='background-color: rgba(78,170,156,1)'></td>
+ <td width='1' style='background-color: rgba(84,175,149,1)'></td>
+ <td width='1' style='background-color: rgba(89,180,144,1)'></td>
+ <td width='1' style='background-color: rgba(94,184,137,1)'></td>
+ <td width='1' style='background-color: rgba(99,190,129,1)'></td>
+ <td width='1' style='background-color: rgba(104,195,123,1)'></td>
+ <td width='1' style='background-color: rgba(109,200,116,1)'></td>
+ <td width='1' style='background-color: rgba(113,205,110,1)'></td>
+ <td width='1' style='background-color: rgba(118,209,104,1)'></td>
+ <td width='1' style='background-color: rgba(124,215,96,1)'></td>
+ <td width='1' style='background-color: rgba(128,220,90,1)'></td>
+ <td width='1' style='background-color: rgba(133,225,83,1)'></td>
+ <td width='1' style='background-color: rgba(138,229,76,1)'></td>
+ <td width='1' style='background-color: rgba(143,235,69,1)'></td>
+ <td width='1' style='background-color: rgba(148,240,63,1)'></td>
+ <td width='1' style='background-color: rgba(154,245,57,1)'></td>
+ <td width='1' style='background-color: rgba(158,250,50,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,43,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(14,105,243,1)'></td>
+ <td width='1' style='background-color: rgba(17,110,236,1)'></td>
+ <td width='1' style='background-color: rgba(21,115,230,1)'></td>
+ <td width='1' style='background-color: rgba(26,119,224,1)'></td>
+ <td width='1' style='background-color: rgba(29,125,216,1)'></td>
+ <td width='1' style='background-color: rgba(34,130,210,1)'></td>
+ <td width='1' style='background-color: rgba(38,135,203,1)'></td>
+ <td width='1' style='background-color: rgba(41,140,196,1)'></td>
+ <td width='1' style='background-color: rgba(46,145,189,1)'></td>
+ <td width='1' style='background-color: rgba(50,150,183,1)'></td>
+ <td width='1' style='background-color: rgba(54,155,177,1)'></td>
+ <td width='1' style='background-color: rgba(58,160,170,1)'></td>
+ <td width='1' style='background-color: rgba(62,164,163,1)'></td>
+ <td width='1' style='background-color: rgba(66,170,156,1)'></td>
+ <td width='1' style='background-color: rgba(70,175,149,1)'></td>
+ <td width='1' style='background-color: rgba(74,180,144,1)'></td>
+ <td width='1' style='background-color: rgba(79,184,137,1)'></td>
+ <td width='1' style='background-color: rgba(82,190,129,1)'></td>
+ <td width='1' style='background-color: rgba(87,195,123,1)'></td>
+ <td width='1' style='background-color: rgba(91,200,116,1)'></td>
+ <td width='1' style='background-color: rgba(94,205,110,1)'></td>
+ <td width='1' style='background-color: rgba(99,209,104,1)'></td>
+ <td width='1' style='background-color: rgba(103,215,96,1)'></td>
+ <td width='1' style='background-color: rgba(107,220,90,1)'></td>
+ <td width='1' style='background-color: rgba(111,225,83,1)'></td>
+ <td width='1' style='background-color: rgba(115,229,76,1)'></td>
+ <td width='1' style='background-color: rgba(119,235,69,1)'></td>
+ <td width='1' style='background-color: rgba(123,240,63,1)'></td>
+ <td width='1' style='background-color: rgba(127,245,57,1)'></td>
+ <td width='1' style='background-color: rgba(131,250,50,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,43,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(13,105,243,1)'></td>
+ <td width='1' style='background-color: rgba(15,110,236,1)'></td>
+ <td width='1' style='background-color: rgba(18,115,229,1)'></td>
+ <td width='1' style='background-color: rgba(21,119,223,1)'></td>
+ <td width='1' style='background-color: rgba(23,125,216,1)'></td>
+ <td width='1' style='background-color: rgba(27,130,209,1)'></td>
+ <td width='1' style='background-color: rgba(30,135,202,1)'></td>
+ <td width='1' style='background-color: rgba(32,140,195,1)'></td>
+ <td width='1' style='background-color: rgba(35,145,188,1)'></td>
+ <td width='1' style='background-color: rgba(38,150,182,1)'></td>
+ <td width='1' style='background-color: rgba(40,155,175,1)'></td>
+ <td width='1' style='background-color: rgba(44,160,168,1)'></td>
+ <td width='1' style='background-color: rgba(47,164,162,1)'></td>
+ <td width='1' style='background-color: rgba(49,170,154,1)'></td>
+ <td width='1' style='background-color: rgba(52,175,147,1)'></td>
+ <td width='1' style='background-color: rgba(55,180,142,1)'></td>
+ <td width='1' style='background-color: rgba(58,184,135,1)'></td>
+ <td width='1' style='background-color: rgba(61,190,127,1)'></td>
+ <td width='1' style='background-color: rgba(64,195,120,1)'></td>
+ <td width='1' style='background-color: rgba(67,200,114,1)'></td>
+ <td width='1' style='background-color: rgba(69,205,107,1)'></td>
+ <td width='1' style='background-color: rgba(72,209,101,1)'></td>
+ <td width='1' style='background-color: rgba(76,215,93,1)'></td>
+ <td width='1' style='background-color: rgba(78,220,87,1)'></td>
+ <td width='1' style='background-color: rgba(81,225,80,1)'></td>
+ <td width='1' style='background-color: rgba(84,229,73,1)'></td>
+ <td width='1' style='background-color: rgba(87,235,65,1)'></td>
+ <td width='1' style='background-color: rgba(90,240,60,1)'></td>
+ <td width='1' style='background-color: rgba(93,245,53,1)'></td>
+ <td width='1' style='background-color: rgba(95,250,46,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,39,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(11,105,242,1)'></td>
+ <td width='1' style='background-color: rgba(11,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(12,115,226,1)'></td>
+ <td width='1' style='background-color: rgba(13,119,219,1)'></td>
+ <td width='1' style='background-color: rgba(14,125,210,1)'></td>
+ <td width='1' style='background-color: rgba(15,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(16,135,194,1)'></td>
+ <td width='1' style='background-color: rgba(16,140,186,1)'></td>
+ <td width='1' style='background-color: rgba(18,145,177,1)'></td>
+ <td width='1' style='background-color: rgba(19,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(19,155,162,1)'></td>
+ <td width='1' style='background-color: rgba(20,160,154,1)'></td>
+ <td width='1' style='background-color: rgba(22,164,146,1)'></td>
+ <td width='1' style='background-color: rgba(22,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(23,175,129,1)'></td>
+ <td width='1' style='background-color: rgba(25,180,122,1)'></td>
+ <td width='1' style='background-color: rgba(26,184,114,1)'></td>
+ <td width='1' style='background-color: rgba(26,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(27,195,97,1)'></td>
+ <td width='1' style='background-color: rgba(29,200,89,1)'></td>
+ <td width='1' style='background-color: rgba(29,205,81,1)'></td>
+ <td width='1' style='background-color: rgba(30,209,74,1)'></td>
+ <td width='1' style='background-color: rgba(31,215,65,1)'></td>
+ <td width='1' style='background-color: rgba(32,220,57,1)'></td>
+ <td width='1' style='background-color: rgba(33,225,49,1)'></td>
+ <td width='1' style='background-color: rgba(34,229,41,1)'></td>
+ <td width='1' style='background-color: rgba(34,235,32,1)'></td>
+ <td width='1' style='background-color: rgba(36,240,25,1)'></td>
+ <td width='1' style='background-color: rgba(37,245,17,1)'></td>
+ <td width='1' style='background-color: rgba(37,250,9,1)'></td>
+ <td width='1' style='background-color: rgba(39,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(11,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(11,110,240,1)'></td>
+ <td width='1' style='background-color: rgba(12,115,235,1)'></td>
+ <td width='1' style='background-color: rgba(13,119,231,1)'></td>
+ <td width='1' style='background-color: rgba(14,125,225,1)'></td>
+ <td width='1' style='background-color: rgba(15,130,220,1)'></td>
+ <td width='1' style='background-color: rgba(16,135,215,1)'></td>
+ <td width='1' style='background-color: rgba(16,140,210,1)'></td>
+ <td width='1' style='background-color: rgba(18,145,205,1)'></td>
+ <td width='1' style='background-color: rgba(19,150,201,1)'></td>
+ <td width='1' style='background-color: rgba(19,155,196,1)'></td>
+ <td width='1' style='background-color: rgba(20,160,191,1)'></td>
+ <td width='1' style='background-color: rgba(22,164,186,1)'></td>
+ <td width='1' style='background-color: rgba(22,170,181,1)'></td>
+ <td width='1' style='background-color: rgba(23,175,176,1)'></td>
+ <td width='1' style='background-color: rgba(25,180,172,1)'></td>
+ <td width='1' style='background-color: rgba(26,184,167,1)'></td>
+ <td width='1' style='background-color: rgba(26,190,161,1)'></td>
+ <td width='1' style='background-color: rgba(27,195,156,1)'></td>
+ <td width='1' style='background-color: rgba(29,200,152,1)'></td>
+ <td width='1' style='background-color: rgba(29,205,147,1)'></td>
+ <td width='1' style='background-color: rgba(30,209,143,1)'></td>
+ <td width='1' style='background-color: rgba(31,215,137,1)'></td>
+ <td width='1' style='background-color: rgba(32,220,132,1)'></td>
+ <td width='1' style='background-color: rgba(33,225,127,1)'></td>
+ <td width='1' style='background-color: rgba(34,229,122,1)'></td>
+ <td width='1' style='background-color: rgba(34,235,117,1)'></td>
+ <td width='1' style='background-color: rgba(36,240,113,1)'></td>
+ <td width='1' style='background-color: rgba(37,245,108,1)'></td>
+ <td width='1' style='background-color: rgba(37,250,103,1)'></td>
+ <td width='1' style='background-color: rgba(39,255,98,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(11,105,246,1)'></td>
+ <td width='1' style='background-color: rgba(11,110,242,1)'></td>
+ <td width='1' style='background-color: rgba(12,115,238,1)'></td>
+ <td width='1' style='background-color: rgba(13,119,235,1)'></td>
+ <td width='1' style='background-color: rgba(13,125,231,1)'></td>
+ <td width='1' style='background-color: rgba(14,130,227,1)'></td>
+ <td width='1' style='background-color: rgba(15,135,224,1)'></td>
+ <td width='1' style='background-color: rgba(15,140,220,1)'></td>
+ <td width='1' style='background-color: rgba(16,145,216,1)'></td>
+ <td width='1' style='background-color: rgba(17,150,213,1)'></td>
+ <td width='1' style='background-color: rgba(18,155,209,1)'></td>
+ <td width='1' style='background-color: rgba(19,160,205,1)'></td>
+ <td width='1' style='background-color: rgba(20,164,202,1)'></td>
+ <td width='1' style='background-color: rgba(20,170,197,1)'></td>
+ <td width='1' style='background-color: rgba(21,175,194,1)'></td>
+ <td width='1' style='background-color: rgba(22,180,191,1)'></td>
+ <td width='1' style='background-color: rgba(23,184,187,1)'></td>
+ <td width='1' style='background-color: rgba(23,190,183,1)'></td>
+ <td width='1' style='background-color: rgba(24,195,179,1)'></td>
+ <td width='1' style='background-color: rgba(25,200,175,1)'></td>
+ <td width='1' style='background-color: rgba(25,205,172,1)'></td>
+ <td width='1' style='background-color: rgba(27,209,169,1)'></td>
+ <td width='1' style='background-color: rgba(28,215,165,1)'></td>
+ <td width='1' style='background-color: rgba(28,220,161,1)'></td>
+ <td width='1' style='background-color: rgba(29,225,157,1)'></td>
+ <td width='1' style='background-color: rgba(30,229,153,1)'></td>
+ <td width='1' style='background-color: rgba(30,235,149,1)'></td>
+ <td width='1' style='background-color: rgba(31,240,146,1)'></td>
+ <td width='1' style='background-color: rgba(32,245,143,1)'></td>
+ <td width='1' style='background-color: rgba(32,250,139,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(11,105,247,1)'></td>
+ <td width='1' style='background-color: rgba(11,110,244,1)'></td>
+ <td width='1' style='background-color: rgba(12,115,241,1)'></td>
+ <td width='1' style='background-color: rgba(13,119,239,1)'></td>
+ <td width='1' style='background-color: rgba(13,125,236,1)'></td>
+ <td width='1' style='background-color: rgba(14,130,233,1)'></td>
+ <td width='1' style='background-color: rgba(15,135,230,1)'></td>
+ <td width='1' style='background-color: rgba(15,140,227,1)'></td>
+ <td width='1' style='background-color: rgba(16,145,224,1)'></td>
+ <td width='1' style='background-color: rgba(17,150,222,1)'></td>
+ <td width='1' style='background-color: rgba(18,155,219,1)'></td>
+ <td width='1' style='background-color: rgba(19,160,216,1)'></td>
+ <td width='1' style='background-color: rgba(20,164,213,1)'></td>
+ <td width='1' style='background-color: rgba(20,170,210,1)'></td>
+ <td width='1' style='background-color: rgba(21,175,207,1)'></td>
+ <td width='1' style='background-color: rgba(22,180,205,1)'></td>
+ <td width='1' style='background-color: rgba(23,184,202,1)'></td>
+ <td width='1' style='background-color: rgba(23,190,199,1)'></td>
+ <td width='1' style='background-color: rgba(24,195,196,1)'></td>
+ <td width='1' style='background-color: rgba(25,200,193,1)'></td>
+ <td width='1' style='background-color: rgba(25,205,190,1)'></td>
+ <td width='1' style='background-color: rgba(27,209,189,1)'></td>
+ <td width='1' style='background-color: rgba(28,215,185,1)'></td>
+ <td width='1' style='background-color: rgba(28,220,182,1)'></td>
+ <td width='1' style='background-color: rgba(29,225,180,1)'></td>
+ <td width='1' style='background-color: rgba(30,229,177,1)'></td>
+ <td width='1' style='background-color: rgba(30,235,173,1)'></td>
+ <td width='1' style='background-color: rgba(31,240,172,1)'></td>
+ <td width='1' style='background-color: rgba(32,245,169,1)'></td>
+ <td width='1' style='background-color: rgba(32,250,166,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,163,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(11,105,247,1)'></td>
+ <td width='1' style='background-color: rgba(11,110,245,1)'></td>
+ <td width='1' style='background-color: rgba(12,115,243,1)'></td>
+ <td width='1' style='background-color: rgba(13,119,242,1)'></td>
+ <td width='1' style='background-color: rgba(13,125,239,1)'></td>
+ <td width='1' style='background-color: rgba(14,130,237,1)'></td>
+ <td width='1' style='background-color: rgba(15,135,235,1)'></td>
+ <td width='1' style='background-color: rgba(15,140,233,1)'></td>
+ <td width='1' style='background-color: rgba(16,145,230,1)'></td>
+ <td width='1' style='background-color: rgba(17,150,229,1)'></td>
+ <td width='1' style='background-color: rgba(18,155,227,1)'></td>
+ <td width='1' style='background-color: rgba(19,160,225,1)'></td>
+ <td width='1' style='background-color: rgba(20,164,223,1)'></td>
+ <td width='1' style='background-color: rgba(20,170,220,1)'></td>
+ <td width='1' style='background-color: rgba(21,175,218,1)'></td>
+ <td width='1' style='background-color: rgba(22,180,217,1)'></td>
+ <td width='1' style='background-color: rgba(23,184,215,1)'></td>
+ <td width='1' style='background-color: rgba(23,190,212,1)'></td>
+ <td width='1' style='background-color: rgba(24,195,210,1)'></td>
+ <td width='1' style='background-color: rgba(25,200,208,1)'></td>
+ <td width='1' style='background-color: rgba(25,205,206,1)'></td>
+ <td width='1' style='background-color: rgba(27,209,205,1)'></td>
+ <td width='1' style='background-color: rgba(28,215,202,1)'></td>
+ <td width='1' style='background-color: rgba(28,220,200,1)'></td>
+ <td width='1' style='background-color: rgba(29,225,198,1)'></td>
+ <td width='1' style='background-color: rgba(30,229,196,1)'></td>
+ <td width='1' style='background-color: rgba(30,235,193,1)'></td>
+ <td width='1' style='background-color: rgba(31,240,192,1)'></td>
+ <td width='1' style='background-color: rgba(32,245,190,1)'></td>
+ <td width='1' style='background-color: rgba(32,250,188,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(11,105,248,1)'></td>
+ <td width='1' style='background-color: rgba(11,110,246,1)'></td>
+ <td width='1' style='background-color: rgba(12,115,245,1)'></td>
+ <td width='1' style='background-color: rgba(13,119,244,1)'></td>
+ <td width='1' style='background-color: rgba(13,125,243,1)'></td>
+ <td width='1' style='background-color: rgba(14,130,241,1)'></td>
+ <td width='1' style='background-color: rgba(15,135,240,1)'></td>
+ <td width='1' style='background-color: rgba(15,140,238,1)'></td>
+ <td width='1' style='background-color: rgba(16,145,236,1)'></td>
+ <td width='1' style='background-color: rgba(17,150,236,1)'></td>
+ <td width='1' style='background-color: rgba(18,155,234,1)'></td>
+ <td width='1' style='background-color: rgba(19,160,233,1)'></td>
+ <td width='1' style='background-color: rgba(20,164,231,1)'></td>
+ <td width='1' style='background-color: rgba(20,170,229,1)'></td>
+ <td width='1' style='background-color: rgba(21,175,228,1)'></td>
+ <td width='1' style='background-color: rgba(22,180,227,1)'></td>
+ <td width='1' style='background-color: rgba(23,184,226,1)'></td>
+ <td width='1' style='background-color: rgba(23,190,224,1)'></td>
+ <td width='1' style='background-color: rgba(24,195,223,1)'></td>
+ <td width='1' style='background-color: rgba(25,200,221,1)'></td>
+ <td width='1' style='background-color: rgba(25,205,219,1)'></td>
+ <td width='1' style='background-color: rgba(27,209,219,1)'></td>
+ <td width='1' style='background-color: rgba(28,215,217,1)'></td>
+ <td width='1' style='background-color: rgba(28,220,216,1)'></td>
+ <td width='1' style='background-color: rgba(29,225,214,1)'></td>
+ <td width='1' style='background-color: rgba(30,229,213,1)'></td>
+ <td width='1' style='background-color: rgba(30,235,211,1)'></td>
+ <td width='1' style='background-color: rgba(31,240,210,1)'></td>
+ <td width='1' style='background-color: rgba(32,245,209,1)'></td>
+ <td width='1' style='background-color: rgba(32,250,207,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,105,249,1)'></td>
+ <td width='1' style='background-color: rgba(10,110,248,1)'></td>
+ <td width='1' style='background-color: rgba(11,115,247,1)'></td>
+ <td width='1' style='background-color: rgba(12,119,247,1)'></td>
+ <td width='1' style='background-color: rgba(12,125,246,1)'></td>
+ <td width='1' style='background-color: rgba(13,130,245,1)'></td>
+ <td width='1' style='background-color: rgba(14,135,244,1)'></td>
+ <td width='1' style='background-color: rgba(14,140,243,1)'></td>
+ <td width='1' style='background-color: rgba(15,145,242,1)'></td>
+ <td width='1' style='background-color: rgba(16,150,242,1)'></td>
+ <td width='1' style='background-color: rgba(15,155,241,1)'></td>
+ <td width='1' style='background-color: rgba(16,160,240,1)'></td>
+ <td width='1' style='background-color: rgba(17,164,239,1)'></td>
+ <td width='1' style='background-color: rgba(17,170,238,1)'></td>
+ <td width='1' style='background-color: rgba(18,175,237,1)'></td>
+ <td width='1' style='background-color: rgba(19,180,237,1)'></td>
+ <td width='1' style='background-color: rgba(20,184,236,1)'></td>
+ <td width='1' style='background-color: rgba(20,190,235,1)'></td>
+ <td width='1' style='background-color: rgba(21,195,234,1)'></td>
+ <td width='1' style='background-color: rgba(22,200,233,1)'></td>
+ <td width='1' style='background-color: rgba(21,205,232,1)'></td>
+ <td width='1' style='background-color: rgba(22,209,232,1)'></td>
+ <td width='1' style='background-color: rgba(23,215,231,1)'></td>
+ <td width='1' style='background-color: rgba(23,220,230,1)'></td>
+ <td width='1' style='background-color: rgba(24,225,229,1)'></td>
+ <td width='1' style='background-color: rgba(25,229,228,1)'></td>
+ <td width='1' style='background-color: rgba(25,235,227,1)'></td>
+ <td width='1' style='background-color: rgba(26,240,227,1)'></td>
+ <td width='1' style='background-color: rgba(27,245,226,1)'></td>
+ <td width='1' style='background-color: rgba(27,250,225,1)'></td>
+ <td width='1' style='background-color: rgba(28,255,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,105,249,1)'></td>
+ <td width='1' style='background-color: rgba(10,110,249,1)'></td>
+ <td width='1' style='background-color: rgba(11,115,248,1)'></td>
+ <td width='1' style='background-color: rgba(12,119,249,1)'></td>
+ <td width='1' style='background-color: rgba(12,125,248,1)'></td>
+ <td width='1' style='background-color: rgba(13,130,248,1)'></td>
+ <td width='1' style='background-color: rgba(14,135,247,1)'></td>
+ <td width='1' style='background-color: rgba(14,140,247,1)'></td>
+ <td width='1' style='background-color: rgba(15,145,246,1)'></td>
+ <td width='1' style='background-color: rgba(16,150,247,1)'></td>
+ <td width='1' style='background-color: rgba(15,155,246,1)'></td>
+ <td width='1' style='background-color: rgba(16,160,246,1)'></td>
+ <td width='1' style='background-color: rgba(17,164,245,1)'></td>
+ <td width='1' style='background-color: rgba(17,170,245,1)'></td>
+ <td width='1' style='background-color: rgba(18,175,244,1)'></td>
+ <td width='1' style='background-color: rgba(19,180,245,1)'></td>
+ <td width='1' style='background-color: rgba(20,184,244,1)'></td>
+ <td width='1' style='background-color: rgba(20,190,244,1)'></td>
+ <td width='1' style='background-color: rgba(21,195,243,1)'></td>
+ <td width='1' style='background-color: rgba(22,200,243,1)'></td>
+ <td width='1' style='background-color: rgba(21,205,242,1)'></td>
+ <td width='1' style='background-color: rgba(22,209,243,1)'></td>
+ <td width='1' style='background-color: rgba(23,215,242,1)'></td>
+ <td width='1' style='background-color: rgba(23,220,242,1)'></td>
+ <td width='1' style='background-color: rgba(24,225,241,1)'></td>
+ <td width='1' style='background-color: rgba(25,229,241,1)'></td>
+ <td width='1' style='background-color: rgba(25,235,240,1)'></td>
+ <td width='1' style='background-color: rgba(26,240,241,1)'></td>
+ <td width='1' style='background-color: rgba(27,245,241,1)'></td>
+ <td width='1' style='background-color: rgba(27,250,240,1)'></td>
+ <td width='1' style='background-color: rgba(28,255,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,105,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,110,250,1)'></td>
+ <td width='1' style='background-color: rgba(11,115,250,1)'></td>
+ <td width='1' style='background-color: rgba(12,119,251,1)'></td>
+ <td width='1' style='background-color: rgba(12,125,251,1)'></td>
+ <td width='1' style='background-color: rgba(13,130,251,1)'></td>
+ <td width='1' style='background-color: rgba(14,135,251,1)'></td>
+ <td width='1' style='background-color: rgba(14,140,251,1)'></td>
+ <td width='1' style='background-color: rgba(15,145,251,1)'></td>
+ <td width='1' style='background-color: rgba(16,150,252,1)'></td>
+ <td width='1' style='background-color: rgba(15,155,252,1)'></td>
+ <td width='1' style='background-color: rgba(16,160,252,1)'></td>
+ <td width='1' style='background-color: rgba(17,164,252,1)'></td>
+ <td width='1' style='background-color: rgba(17,170,252,1)'></td>
+ <td width='1' style='background-color: rgba(18,175,252,1)'></td>
+ <td width='1' style='background-color: rgba(19,180,253,1)'></td>
+ <td width='1' style='background-color: rgba(20,184,253,1)'></td>
+ <td width='1' style='background-color: rgba(20,190,253,1)'></td>
+ <td width='1' style='background-color: rgba(21,195,253,1)'></td>
+ <td width='1' style='background-color: rgba(22,200,253,1)'></td>
+ <td width='1' style='background-color: rgba(21,205,253,1)'></td>
+ <td width='1' style='background-color: rgba(22,209,254,1)'></td>
+ <td width='1' style='background-color: rgba(23,215,254,1)'></td>
+ <td width='1' style='background-color: rgba(23,220,254,1)'></td>
+ <td width='1' style='background-color: rgba(24,225,254,1)'></td>
+ <td width='1' style='background-color: rgba(25,229,254,1)'></td>
+ <td width='1' style='background-color: rgba(25,235,254,1)'></td>
+ <td width='1' style='background-color: rgba(26,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(27,245,255,1)'></td>
+ <td width='1' style='background-color: rgba(27,250,255,1)'></td>
+ <td width='1' style='background-color: rgba(28,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,104,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,109,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,113,250,1)'></td>
+ <td width='1' style='background-color: rgba(11,117,251,1)'></td>
+ <td width='1' style='background-color: rgba(11,122,251,1)'></td>
+ <td width='1' style='background-color: rgba(12,127,251,1)'></td>
+ <td width='1' style='background-color: rgba(12,131,251,1)'></td>
+ <td width='1' style='background-color: rgba(12,136,251,1)'></td>
+ <td width='1' style='background-color: rgba(13,140,251,1)'></td>
+ <td width='1' style='background-color: rgba(13,145,252,1)'></td>
+ <td width='1' style='background-color: rgba(13,149,252,1)'></td>
+ <td width='1' style='background-color: rgba(14,154,252,1)'></td>
+ <td width='1' style='background-color: rgba(14,157,252,1)'></td>
+ <td width='1' style='background-color: rgba(14,163,252,1)'></td>
+ <td width='1' style='background-color: rgba(15,167,252,1)'></td>
+ <td width='1' style='background-color: rgba(15,172,253,1)'></td>
+ <td width='1' style='background-color: rgba(16,175,253,1)'></td>
+ <td width='1' style='background-color: rgba(16,181,253,1)'></td>
+ <td width='1' style='background-color: rgba(16,185,253,1)'></td>
+ <td width='1' style='background-color: rgba(17,190,253,1)'></td>
+ <td width='1' style='background-color: rgba(17,194,253,1)'></td>
+ <td width='1' style='background-color: rgba(17,198,254,1)'></td>
+ <td width='1' style='background-color: rgba(18,203,254,1)'></td>
+ <td width='1' style='background-color: rgba(18,208,254,1)'></td>
+ <td width='1' style='background-color: rgba(18,212,254,1)'></td>
+ <td width='1' style='background-color: rgba(19,216,254,1)'></td>
+ <td width='1' style='background-color: rgba(19,221,254,1)'></td>
+ <td width='1' style='background-color: rgba(19,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(20,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(20,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,240,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,104,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,108,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,112,250,1)'></td>
+ <td width='1' style='background-color: rgba(11,115,251,1)'></td>
+ <td width='1' style='background-color: rgba(11,120,251,1)'></td>
+ <td width='1' style='background-color: rgba(12,124,251,1)'></td>
+ <td width='1' style='background-color: rgba(12,128,251,1)'></td>
+ <td width='1' style='background-color: rgba(12,132,251,1)'></td>
+ <td width='1' style='background-color: rgba(13,136,251,1)'></td>
+ <td width='1' style='background-color: rgba(13,140,252,1)'></td>
+ <td width='1' style='background-color: rgba(13,144,252,1)'></td>
+ <td width='1' style='background-color: rgba(14,148,252,1)'></td>
+ <td width='1' style='background-color: rgba(14,151,252,1)'></td>
+ <td width='1' style='background-color: rgba(14,156,252,1)'></td>
+ <td width='1' style='background-color: rgba(15,160,252,1)'></td>
+ <td width='1' style='background-color: rgba(15,164,253,1)'></td>
+ <td width='1' style='background-color: rgba(16,167,253,1)'></td>
+ <td width='1' style='background-color: rgba(16,172,253,1)'></td>
+ <td width='1' style='background-color: rgba(16,176,253,1)'></td>
+ <td width='1' style='background-color: rgba(17,180,253,1)'></td>
+ <td width='1' style='background-color: rgba(17,184,253,1)'></td>
+ <td width='1' style='background-color: rgba(17,187,254,1)'></td>
+ <td width='1' style='background-color: rgba(18,192,254,1)'></td>
+ <td width='1' style='background-color: rgba(18,196,254,1)'></td>
+ <td width='1' style='background-color: rgba(18,200,254,1)'></td>
+ <td width='1' style='background-color: rgba(19,203,254,1)'></td>
+ <td width='1' style='background-color: rgba(19,208,254,1)'></td>
+ <td width='1' style='background-color: rgba(19,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(20,216,255,1)'></td>
+ <td width='1' style='background-color: rgba(20,220,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,224,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,103,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,106,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,110,250,1)'></td>
+ <td width='1' style='background-color: rgba(11,112,251,1)'></td>
+ <td width='1' style='background-color: rgba(11,117,251,1)'></td>
+ <td width='1' style='background-color: rgba(12,120,251,1)'></td>
+ <td width='1' style='background-color: rgba(12,124,251,1)'></td>
+ <td width='1' style='background-color: rgba(12,127,251,1)'></td>
+ <td width='1' style='background-color: rgba(13,130,251,1)'></td>
+ <td width='1' style='background-color: rgba(13,134,252,1)'></td>
+ <td width='1' style='background-color: rgba(13,137,252,1)'></td>
+ <td width='1' style='background-color: rgba(14,141,252,1)'></td>
+ <td width='1' style='background-color: rgba(14,143,252,1)'></td>
+ <td width='1' style='background-color: rgba(14,147,252,1)'></td>
+ <td width='1' style='background-color: rgba(15,151,252,1)'></td>
+ <td width='1' style='background-color: rgba(15,154,253,1)'></td>
+ <td width='1' style='background-color: rgba(16,157,253,1)'></td>
+ <td width='1' style='background-color: rgba(16,161,253,1)'></td>
+ <td width='1' style='background-color: rgba(16,165,253,1)'></td>
+ <td width='1' style='background-color: rgba(17,168,253,1)'></td>
+ <td width='1' style='background-color: rgba(17,171,253,1)'></td>
+ <td width='1' style='background-color: rgba(17,174,254,1)'></td>
+ <td width='1' style='background-color: rgba(18,178,254,1)'></td>
+ <td width='1' style='background-color: rgba(18,182,254,1)'></td>
+ <td width='1' style='background-color: rgba(18,185,254,1)'></td>
+ <td width='1' style='background-color: rgba(19,188,254,1)'></td>
+ <td width='1' style='background-color: rgba(19,192,254,1)'></td>
+ <td width='1' style='background-color: rgba(19,195,255,1)'></td>
+ <td width='1' style='background-color: rgba(20,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(20,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,206,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,102,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,105,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,108,250,1)'></td>
+ <td width='1' style='background-color: rgba(11,110,251,1)'></td>
+ <td width='1' style='background-color: rgba(11,113,251,1)'></td>
+ <td width='1' style='background-color: rgba(12,116,251,1)'></td>
+ <td width='1' style='background-color: rgba(12,119,251,1)'></td>
+ <td width='1' style='background-color: rgba(12,122,251,1)'></td>
+ <td width='1' style='background-color: rgba(13,124,251,1)'></td>
+ <td width='1' style='background-color: rgba(13,127,252,1)'></td>
+ <td width='1' style='background-color: rgba(13,130,252,1)'></td>
+ <td width='1' style='background-color: rgba(14,133,252,1)'></td>
+ <td width='1' style='background-color: rgba(14,135,252,1)'></td>
+ <td width='1' style='background-color: rgba(14,138,252,1)'></td>
+ <td width='1' style='background-color: rgba(15,141,252,1)'></td>
+ <td width='1' style='background-color: rgba(15,144,253,1)'></td>
+ <td width='1' style='background-color: rgba(16,146,253,1)'></td>
+ <td width='1' style='background-color: rgba(16,149,253,1)'></td>
+ <td width='1' style='background-color: rgba(16,152,253,1)'></td>
+ <td width='1' style='background-color: rgba(17,155,253,1)'></td>
+ <td width='1' style='background-color: rgba(17,158,253,1)'></td>
+ <td width='1' style='background-color: rgba(17,160,254,1)'></td>
+ <td width='1' style='background-color: rgba(18,163,254,1)'></td>
+ <td width='1' style='background-color: rgba(18,166,254,1)'></td>
+ <td width='1' style='background-color: rgba(18,169,254,1)'></td>
+ <td width='1' style='background-color: rgba(19,171,254,1)'></td>
+ <td width='1' style='background-color: rgba(19,174,254,1)'></td>
+ <td width='1' style='background-color: rgba(19,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(20,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(20,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,186,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,102,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,104,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,106,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,107,251,1)'></td>
+ <td width='1' style='background-color: rgba(8,110,251,1)'></td>
+ <td width='1' style='background-color: rgba(8,112,251,1)'></td>
+ <td width='1' style='background-color: rgba(8,114,251,1)'></td>
+ <td width='1' style='background-color: rgba(7,116,251,1)'></td>
+ <td width='1' style='background-color: rgba(7,118,251,1)'></td>
+ <td width='1' style='background-color: rgba(7,120,252,1)'></td>
+ <td width='1' style='background-color: rgba(6,122,252,1)'></td>
+ <td width='1' style='background-color: rgba(6,125,252,1)'></td>
+ <td width='1' style='background-color: rgba(6,126,252,1)'></td>
+ <td width='1' style='background-color: rgba(5,128,252,1)'></td>
+ <td width='1' style='background-color: rgba(5,131,252,1)'></td>
+ <td width='1' style='background-color: rgba(5,133,253,1)'></td>
+ <td width='1' style='background-color: rgba(5,134,253,1)'></td>
+ <td width='1' style='background-color: rgba(4,137,253,1)'></td>
+ <td width='1' style='background-color: rgba(4,139,253,1)'></td>
+ <td width='1' style='background-color: rgba(4,141,253,1)'></td>
+ <td width='1' style='background-color: rgba(3,143,253,1)'></td>
+ <td width='1' style='background-color: rgba(3,144,254,1)'></td>
+ <td width='1' style='background-color: rgba(3,147,254,1)'></td>
+ <td width='1' style='background-color: rgba(2,149,254,1)'></td>
+ <td width='1' style='background-color: rgba(2,151,254,1)'></td>
+ <td width='1' style='background-color: rgba(2,152,254,1)'></td>
+ <td width='1' style='background-color: rgba(1,155,254,1)'></td>
+ <td width='1' style='background-color: rgba(1,157,255,1)'></td>
+ <td width='1' style='background-color: rgba(1,160,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,162,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,164,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,101,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,102,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,103,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,104,251,1)'></td>
+ <td width='1' style='background-color: rgba(8,105,251,1)'></td>
+ <td width='1' style='background-color: rgba(8,107,251,1)'></td>
+ <td width='1' style='background-color: rgba(8,108,251,1)'></td>
+ <td width='1' style='background-color: rgba(7,109,251,1)'></td>
+ <td width='1' style='background-color: rgba(7,110,251,1)'></td>
+ <td width='1' style='background-color: rgba(7,111,252,1)'></td>
+ <td width='1' style='background-color: rgba(6,113,252,1)'></td>
+ <td width='1' style='background-color: rgba(6,114,252,1)'></td>
+ <td width='1' style='background-color: rgba(6,114,252,1)'></td>
+ <td width='1' style='background-color: rgba(5,116,252,1)'></td>
+ <td width='1' style='background-color: rgba(5,117,252,1)'></td>
+ <td width='1' style='background-color: rgba(5,118,253,1)'></td>
+ <td width='1' style='background-color: rgba(5,119,253,1)'></td>
+ <td width='1' style='background-color: rgba(4,120,253,1)'></td>
+ <td width='1' style='background-color: rgba(4,122,253,1)'></td>
+ <td width='1' style='background-color: rgba(4,123,253,1)'></td>
+ <td width='1' style='background-color: rgba(3,124,253,1)'></td>
+ <td width='1' style='background-color: rgba(3,125,254,1)'></td>
+ <td width='1' style='background-color: rgba(3,126,254,1)'></td>
+ <td width='1' style='background-color: rgba(2,128,254,1)'></td>
+ <td width='1' style='background-color: rgba(2,129,254,1)'></td>
+ <td width='1' style='background-color: rgba(2,129,254,1)'></td>
+ <td width='1' style='background-color: rgba(1,131,254,1)'></td>
+ <td width='1' style='background-color: rgba(1,132,255,1)'></td>
+ <td width='1' style='background-color: rgba(1,133,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,135,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,136,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,99,251,1)'></td>
+ <td width='1' style='background-color: rgba(8,99,251,1)'></td>
+ <td width='1' style='background-color: rgba(8,100,251,1)'></td>
+ <td width='1' style='background-color: rgba(8,100,251,1)'></td>
+ <td width='1' style='background-color: rgba(7,100,251,1)'></td>
+ <td width='1' style='background-color: rgba(7,99,251,1)'></td>
+ <td width='1' style='background-color: rgba(7,99,252,1)'></td>
+ <td width='1' style='background-color: rgba(6,99,252,1)'></td>
+ <td width='1' style='background-color: rgba(6,100,252,1)'></td>
+ <td width='1' style='background-color: rgba(6,99,252,1)'></td>
+ <td width='1' style='background-color: rgba(5,99,252,1)'></td>
+ <td width='1' style='background-color: rgba(5,99,252,1)'></td>
+ <td width='1' style='background-color: rgba(5,99,253,1)'></td>
+ <td width='1' style='background-color: rgba(5,98,253,1)'></td>
+ <td width='1' style='background-color: rgba(4,99,253,1)'></td>
+ <td width='1' style='background-color: rgba(4,99,253,1)'></td>
+ <td width='1' style='background-color: rgba(4,99,253,1)'></td>
+ <td width='1' style='background-color: rgba(3,99,253,1)'></td>
+ <td width='1' style='background-color: rgba(3,98,254,1)'></td>
+ <td width='1' style='background-color: rgba(3,99,254,1)'></td>
+ <td width='1' style='background-color: rgba(2,99,254,1)'></td>
+ <td width='1' style='background-color: rgba(2,99,254,1)'></td>
+ <td width='1' style='background-color: rgba(2,98,254,1)'></td>
+ <td width='1' style='background-color: rgba(1,99,254,1)'></td>
+ <td width='1' style='background-color: rgba(1,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(1,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-background/bg__6a16.html b/image/test/reftest/pngsuite-background/bg__6a16.html
new file mode 100644
index 0000000000..8ead05a34f
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/bg__6a16.html
@@ -0,0 +1,1092 @@
+<html><body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(24,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(24,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(24,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(23,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(23,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(23,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(23,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(22,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(22,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(22,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(21,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(21,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(21,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(20,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(20,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(20,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(19,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(19,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(18,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(18,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(17,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(17,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(16,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(16,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(15,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(14,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(13,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(12,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(9,110,234,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,109,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(41,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(40,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(40,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(39,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(39,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(38,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(37,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(37,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(36,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(35,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(35,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(34,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(33,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(32,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(31,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(31,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(29,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(29,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(28,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(26,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(25,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(24,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(22,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(21,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(19,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(16,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(9,120,218,1)'></td>
+ <td width='1' style='background-color: rgba(9,109,237,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,109,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,119,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(56,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(55,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(54,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(53,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(52,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(51,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(50,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(49,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(47,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(46,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(45,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(44,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(43,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(41,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(40,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(38,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(37,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(35,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(33,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(31,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(29,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(26,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(23,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(19,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(8,130,202,1)'></td>
+ <td width='1' style='background-color: rgba(9,119,225,1)'></td>
+ <td width='1' style='background-color: rgba(9,109,238,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,109,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,118,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,129,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(71,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(70,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(68,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(67,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(66,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(64,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(62,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(61,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(59,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(57,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(56,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(54,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(52,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(49,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(47,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(45,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(42,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(39,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(36,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(33,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(28,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(22,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(7,140,185,1)'></td>
+ <td width='1' style='background-color: rgba(8,129,213,1)'></td>
+ <td width='1' style='background-color: rgba(9,118,228,1)'></td>
+ <td width='1' style='background-color: rgba(9,109,239,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,108,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,118,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,128,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,138,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(87,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(85,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(83,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(81,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(79,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(77,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(75,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(72,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(70,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(68,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(65,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(62,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(59,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(56,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(53,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(49,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(45,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(40,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(34,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(27,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(7,150,170,1)'></td>
+ <td width='1' style='background-color: rgba(7,138,200,1)'></td>
+ <td width='1' style='background-color: rgba(8,128,217,1)'></td>
+ <td width='1' style='background-color: rgba(9,118,230,1)'></td>
+ <td width='1' style='background-color: rgba(9,108,240,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,108,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,117,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,127,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,137,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,148,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(102,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(99,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(97,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(94,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(92,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(89,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(86,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(83,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(79,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(76,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(72,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(68,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(64,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(59,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(54,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(48,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(41,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(32,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(6,160,153,1)'></td>
+ <td width='1' style='background-color: rgba(7,148,190,1)'></td>
+ <td width='1' style='background-color: rgba(7,137,206,1)'></td>
+ <td width='1' style='background-color: rgba(8,127,220,1)'></td>
+ <td width='1' style='background-color: rgba(9,117,231,1)'></td>
+ <td width='1' style='background-color: rgba(9,108,241,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,108,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,117,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,126,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,135,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,146,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,157,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(116,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(113,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(110,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(106,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(103,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(99,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(95,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(91,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(86,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(81,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(76,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(70,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(64,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(57,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(48,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(36,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(5,170,137,1)'></td>
+ <td width='1' style='background-color: rgba(6,157,179,1)'></td>
+ <td width='1' style='background-color: rgba(7,146,197,1)'></td>
+ <td width='1' style='background-color: rgba(7,135,211,1)'></td>
+ <td width='1' style='background-color: rgba(8,126,223,1)'></td>
+ <td width='1' style='background-color: rgba(9,117,233,1)'></td>
+ <td width='1' style='background-color: rgba(9,108,241,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,108,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,116,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,125,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,134,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,144,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,154,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,166,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(132,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(128,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(124,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(119,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(114,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(109,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(104,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(98,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(91,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(85,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(77,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(68,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(57,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(43,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(5,180,121,1)'></td>
+ <td width='1' style='background-color: rgba(5,166,168,1)'></td>
+ <td width='1' style='background-color: rgba(6,154,188,1)'></td>
+ <td width='1' style='background-color: rgba(7,144,203,1)'></td>
+ <td width='1' style='background-color: rgba(7,134,214,1)'></td>
+ <td width='1' style='background-color: rgba(8,125,225,1)'></td>
+ <td width='1' style='background-color: rgba(9,116,234,1)'></td>
+ <td width='1' style='background-color: rgba(9,108,242,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,107,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,115,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,124,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,133,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,142,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,152,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,163,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,175,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(146,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(140,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(135,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(129,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(122,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(115,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(107,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(99,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(90,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(80,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(67,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(49,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(4,190,105,1)'></td>
+ <td width='1' style='background-color: rgba(5,175,159,1)'></td>
+ <td width='1' style='background-color: rgba(5,163,180,1)'></td>
+ <td width='1' style='background-color: rgba(6,152,195,1)'></td>
+ <td width='1' style='background-color: rgba(7,142,208,1)'></td>
+ <td width='1' style='background-color: rgba(7,133,217,1)'></td>
+ <td width='1' style='background-color: rgba(8,124,227,1)'></td>
+ <td width='1' style='background-color: rgba(9,115,235,1)'></td>
+ <td width='1' style='background-color: rgba(9,107,242,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,107,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,115,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,123,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,131,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,140,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,149,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,160,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,171,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,184,105,1)'></td>
+ <td width='1' style='background-color: rgba(169,200,88,1)'></td>
+ <td width='1' style='background-color: rgba(161,200,88,1)'></td>
+ <td width='1' style='background-color: rgba(154,200,88,1)'></td>
+ <td width='1' style='background-color: rgba(147,200,88,1)'></td>
+ <td width='1' style='background-color: rgba(138,200,88,1)'></td>
+ <td width='1' style='background-color: rgba(129,200,88,1)'></td>
+ <td width='1' style='background-color: rgba(119,200,88,1)'></td>
+ <td width='1' style='background-color: rgba(108,200,88,1)'></td>
+ <td width='1' style='background-color: rgba(95,200,88,1)'></td>
+ <td width='1' style='background-color: rgba(79,200,88,1)'></td>
+ <td width='1' style='background-color: rgba(59,200,88,1)'></td>
+ <td width='1' style='background-color: rgba(4,200,88,1)'></td>
+ <td width='1' style='background-color: rgba(4,184,150,1)'></td>
+ <td width='1' style='background-color: rgba(5,171,173,1)'></td>
+ <td width='1' style='background-color: rgba(5,160,189,1)'></td>
+ <td width='1' style='background-color: rgba(6,149,201,1)'></td>
+ <td width='1' style='background-color: rgba(7,140,212,1)'></td>
+ <td width='1' style='background-color: rgba(7,131,220,1)'></td>
+ <td width='1' style='background-color: rgba(8,123,229,1)'></td>
+ <td width='1' style='background-color: rgba(9,115,237,1)'></td>
+ <td width='1' style='background-color: rgba(9,107,243,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,107,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,114,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,122,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,129,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,138,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,147,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,156,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,167,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,178,105,1)'></td>
+ <td width='1' style='background-color: rgba(169,192,88,1)'></td>
+ <td width='1' style='background-color: rgba(184,210,73,1)'></td>
+ <td width='1' style='background-color: rgba(174,210,73,1)'></td>
+ <td width='1' style='background-color: rgba(164,210,73,1)'></td>
+ <td width='1' style='background-color: rgba(153,210,73,1)'></td>
+ <td width='1' style='background-color: rgba(141,210,73,1)'></td>
+ <td width='1' style='background-color: rgba(127,210,73,1)'></td>
+ <td width='1' style='background-color: rgba(113,210,73,1)'></td>
+ <td width='1' style='background-color: rgba(94,210,73,1)'></td>
+ <td width='1' style='background-color: rgba(69,210,73,1)'></td>
+ <td width='1' style='background-color: rgba(3,210,73,1)'></td>
+ <td width='1' style='background-color: rgba(4,192,143,1)'></td>
+ <td width='1' style='background-color: rgba(4,178,168,1)'></td>
+ <td width='1' style='background-color: rgba(5,167,184,1)'></td>
+ <td width='1' style='background-color: rgba(5,156,196,1)'></td>
+ <td width='1' style='background-color: rgba(6,147,206,1)'></td>
+ <td width='1' style='background-color: rgba(7,138,216,1)'></td>
+ <td width='1' style='background-color: rgba(7,129,223,1)'></td>
+ <td width='1' style='background-color: rgba(8,122,231,1)'></td>
+ <td width='1' style='background-color: rgba(9,114,238,1)'></td>
+ <td width='1' style='background-color: rgba(9,107,243,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,106,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,113,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,120,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,128,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,136,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,144,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,153,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,162,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,173,105,1)'></td>
+ <td width='1' style='background-color: rgba(169,185,88,1)'></td>
+ <td width='1' style='background-color: rgba(184,200,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,220,57,1)'></td>
+ <td width='1' style='background-color: rgba(185,220,57,1)'></td>
+ <td width='1' style='background-color: rgba(171,220,57,1)'></td>
+ <td width='1' style='background-color: rgba(154,220,57,1)'></td>
+ <td width='1' style='background-color: rgba(135,220,57,1)'></td>
+ <td width='1' style='background-color: rgba(113,220,57,1)'></td>
+ <td width='1' style='background-color: rgba(83,220,57,1)'></td>
+ <td width='1' style='background-color: rgba(2,220,57,1)'></td>
+ <td width='1' style='background-color: rgba(3,200,139,1)'></td>
+ <td width='1' style='background-color: rgba(4,185,163,1)'></td>
+ <td width='1' style='background-color: rgba(4,173,181,1)'></td>
+ <td width='1' style='background-color: rgba(5,162,193,1)'></td>
+ <td width='1' style='background-color: rgba(5,153,202,1)'></td>
+ <td width='1' style='background-color: rgba(6,144,211,1)'></td>
+ <td width='1' style='background-color: rgba(7,136,219,1)'></td>
+ <td width='1' style='background-color: rgba(7,128,225,1)'></td>
+ <td width='1' style='background-color: rgba(8,120,232,1)'></td>
+ <td width='1' style='background-color: rgba(9,113,238,1)'></td>
+ <td width='1' style='background-color: rgba(9,106,244,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,106,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,113,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,119,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,126,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,133,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,141,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,149,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,157,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,167,105,1)'></td>
+ <td width='1' style='background-color: rgba(169,178,88,1)'></td>
+ <td width='1' style='background-color: rgba(184,190,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,206,57,1)'></td>
+ <td width='1' style='background-color: rgba(216,230,40,1)'></td>
+ <td width='1' style='background-color: rgba(195,230,40,1)'></td>
+ <td width='1' style='background-color: rgba(171,230,40,1)'></td>
+ <td width='1' style='background-color: rgba(142,230,40,1)'></td>
+ <td width='1' style='background-color: rgba(105,230,40,1)'></td>
+ <td width='1' style='background-color: rgba(2,230,40,1)'></td>
+ <td width='1' style='background-color: rgba(2,206,138,1)'></td>
+ <td width='1' style='background-color: rgba(3,190,164,1)'></td>
+ <td width='1' style='background-color: rgba(4,178,179,1)'></td>
+ <td width='1' style='background-color: rgba(4,167,191,1)'></td>
+ <td width='1' style='background-color: rgba(5,157,201,1)'></td>
+ <td width='1' style='background-color: rgba(5,149,208,1)'></td>
+ <td width='1' style='background-color: rgba(6,141,215,1)'></td>
+ <td width='1' style='background-color: rgba(7,133,222,1)'></td>
+ <td width='1' style='background-color: rgba(7,126,227,1)'></td>
+ <td width='1' style='background-color: rgba(8,119,234,1)'></td>
+ <td width='1' style='background-color: rgba(9,113,240,1)'></td>
+ <td width='1' style='background-color: rgba(9,106,244,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,106,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,112,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,118,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,124,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,131,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,138,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,145,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,152,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,160,105,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,88,1)'></td>
+ <td width='1' style='background-color: rgba(184,179,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,192,57,1)'></td>
+ <td width='1' style='background-color: rgba(216,209,40,1)'></td>
+ <td width='1' style='background-color: rgba(231,240,25,1)'></td>
+ <td width='1' style='background-color: rgba(192,240,25,1)'></td>
+ <td width='1' style='background-color: rgba(140,240,25,1)'></td>
+ <td width='1' style='background-color: rgba(1,240,25,1)'></td>
+ <td width='1' style='background-color: rgba(2,209,143,1)'></td>
+ <td width='1' style='background-color: rgba(2,192,168,1)'></td>
+ <td width='1' style='background-color: rgba(3,179,183,1)'></td>
+ <td width='1' style='background-color: rgba(4,169,192,1)'></td>
+ <td width='1' style='background-color: rgba(4,160,200,1)'></td>
+ <td width='1' style='background-color: rgba(5,152,207,1)'></td>
+ <td width='1' style='background-color: rgba(5,145,213,1)'></td>
+ <td width='1' style='background-color: rgba(6,138,219,1)'></td>
+ <td width='1' style='background-color: rgba(7,131,225,1)'></td>
+ <td width='1' style='background-color: rgba(7,124,230,1)'></td>
+ <td width='1' style='background-color: rgba(8,118,235,1)'></td>
+ <td width='1' style='background-color: rgba(9,112,240,1)'></td>
+ <td width='1' style='background-color: rgba(9,106,245,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,105,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,111,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,117,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,123,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,129,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,134,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,141,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,147,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,153,105,1)'></td>
+ <td width='1' style='background-color: rgba(169,160,88,1)'></td>
+ <td width='1' style='background-color: rgba(184,167,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,175,57,1)'></td>
+ <td width='1' style='background-color: rgba(216,185,40,1)'></td>
+ <td width='1' style='background-color: rgba(231,201,25,1)'></td>
+ <td width='1' style='background-color: rgba(247,250,8,1)'></td>
+ <td width='1' style='background-color: rgba(0,250,8,1)'></td>
+ <td width='1' style='background-color: rgba(1,201,164,1)'></td>
+ <td width='1' style='background-color: rgba(2,185,180,1)'></td>
+ <td width='1' style='background-color: rgba(2,175,190,1)'></td>
+ <td width='1' style='background-color: rgba(3,167,197,1)'></td>
+ <td width='1' style='background-color: rgba(4,160,203,1)'></td>
+ <td width='1' style='background-color: rgba(4,153,208,1)'></td>
+ <td width='1' style='background-color: rgba(5,147,214,1)'></td>
+ <td width='1' style='background-color: rgba(5,141,218,1)'></td>
+ <td width='1' style='background-color: rgba(6,134,223,1)'></td>
+ <td width='1' style='background-color: rgba(7,129,228,1)'></td>
+ <td width='1' style='background-color: rgba(7,123,232,1)'></td>
+ <td width='1' style='background-color: rgba(8,117,237,1)'></td>
+ <td width='1' style='background-color: rgba(9,111,241,1)'></td>
+ <td width='1' style='background-color: rgba(9,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,105,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,110,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,116,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,121,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,126,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,131,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,136,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,141,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,145,105,1)'></td>
+ <td width='1' style='background-color: rgba(169,150,88,1)'></td>
+ <td width='1' style='background-color: rgba(184,153,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,156,57,1)'></td>
+ <td width='1' style='background-color: rgba(216,156,40,1)'></td>
+ <td width='1' style='background-color: rgba(231,149,25,1)'></td>
+ <td width='1' style='background-color: rgba(247,3,8,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,255,1)'></td>
+ <td width='1' style='background-color: rgba(1,149,216,1)'></td>
+ <td width='1' style='background-color: rgba(2,156,209,1)'></td>
+ <td width='1' style='background-color: rgba(2,156,209,1)'></td>
+ <td width='1' style='background-color: rgba(3,153,211,1)'></td>
+ <td width='1' style='background-color: rgba(4,150,213,1)'></td>
+ <td width='1' style='background-color: rgba(4,145,216,1)'></td>
+ <td width='1' style='background-color: rgba(5,141,220,1)'></td>
+ <td width='1' style='background-color: rgba(5,136,223,1)'></td>
+ <td width='1' style='background-color: rgba(6,131,226,1)'></td>
+ <td width='1' style='background-color: rgba(7,126,231,1)'></td>
+ <td width='1' style='background-color: rgba(7,121,234,1)'></td>
+ <td width='1' style='background-color: rgba(8,116,238,1)'></td>
+ <td width='1' style='background-color: rgba(9,110,242,1)'></td>
+ <td width='1' style='background-color: rgba(9,105,245,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,105,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,109,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,114,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,119,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,123,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,127,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,131,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,134,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,137,105,1)'></td>
+ <td width='1' style='background-color: rgba(169,139,88,1)'></td>
+ <td width='1' style='background-color: rgba(184,139,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,134,57,1)'></td>
+ <td width='1' style='background-color: rgba(216,119,40,1)'></td>
+ <td width='1' style='background-color: rgba(231,10,25,1)'></td>
+ <td width='1' style='background-color: rgba(192,10,164,1)'></td>
+ <td width='1' style='background-color: rgba(140,10,216,1)'></td>
+ <td width='1' style='background-color: rgba(1,10,255,1)'></td>
+ <td width='1' style='background-color: rgba(2,119,233,1)'></td>
+ <td width='1' style='background-color: rgba(2,134,226,1)'></td>
+ <td width='1' style='background-color: rgba(3,139,223,1)'></td>
+ <td width='1' style='background-color: rgba(4,139,222,1)'></td>
+ <td width='1' style='background-color: rgba(4,137,223,1)'></td>
+ <td width='1' style='background-color: rgba(5,134,225,1)'></td>
+ <td width='1' style='background-color: rgba(5,131,227,1)'></td>
+ <td width='1' style='background-color: rgba(6,127,230,1)'></td>
+ <td width='1' style='background-color: rgba(7,123,233,1)'></td>
+ <td width='1' style='background-color: rgba(7,119,235,1)'></td>
+ <td width='1' style='background-color: rgba(8,114,239,1)'></td>
+ <td width='1' style='background-color: rgba(9,109,243,1)'></td>
+ <td width='1' style='background-color: rgba(9,105,246,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,104,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,109,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,113,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,116,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,120,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,123,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,126,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,128,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,128,105,1)'></td>
+ <td width='1' style='background-color: rgba(169,126,88,1)'></td>
+ <td width='1' style='background-color: rgba(184,120,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,104,57,1)'></td>
+ <td width='1' style='background-color: rgba(216,16,40,1)'></td>
+ <td width='1' style='background-color: rgba(195,16,143,1)'></td>
+ <td width='1' style='background-color: rgba(171,16,180,1)'></td>
+ <td width='1' style='background-color: rgba(142,16,209,1)'></td>
+ <td width='1' style='background-color: rgba(105,16,233,1)'></td>
+ <td width='1' style='background-color: rgba(2,16,254,1)'></td>
+ <td width='1' style='background-color: rgba(2,104,240,1)'></td>
+ <td width='1' style='background-color: rgba(3,120,234,1)'></td>
+ <td width='1' style='background-color: rgba(4,126,231,1)'></td>
+ <td width='1' style='background-color: rgba(4,128,230,1)'></td>
+ <td width='1' style='background-color: rgba(5,128,230,1)'></td>
+ <td width='1' style='background-color: rgba(5,126,231,1)'></td>
+ <td width='1' style='background-color: rgba(6,123,233,1)'></td>
+ <td width='1' style='background-color: rgba(7,120,235,1)'></td>
+ <td width='1' style='background-color: rgba(7,116,237,1)'></td>
+ <td width='1' style='background-color: rgba(8,113,240,1)'></td>
+ <td width='1' style='background-color: rgba(9,109,244,1)'></td>
+ <td width='1' style='background-color: rgba(9,104,246,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,104,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,107,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,111,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,114,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,117,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,119,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,120,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,118,105,1)'></td>
+ <td width='1' style='background-color: rgba(169,110,88,1)'></td>
+ <td width='1' style='background-color: rgba(184,95,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,23,57,1)'></td>
+ <td width='1' style='background-color: rgba(185,23,138,1)'></td>
+ <td width='1' style='background-color: rgba(171,23,168,1)'></td>
+ <td width='1' style='background-color: rgba(154,23,190,1)'></td>
+ <td width='1' style='background-color: rgba(135,23,209,1)'></td>
+ <td width='1' style='background-color: rgba(113,23,226,1)'></td>
+ <td width='1' style='background-color: rgba(83,23,240,1)'></td>
+ <td width='1' style='background-color: rgba(2,23,254,1)'></td>
+ <td width='1' style='background-color: rgba(3,95,244,1)'></td>
+ <td width='1' style='background-color: rgba(4,110,238,1)'></td>
+ <td width='1' style='background-color: rgba(4,118,236,1)'></td>
+ <td width='1' style='background-color: rgba(5,120,235,1)'></td>
+ <td width='1' style='background-color: rgba(5,120,235,1)'></td>
+ <td width='1' style='background-color: rgba(6,119,236,1)'></td>
+ <td width='1' style='background-color: rgba(7,117,238,1)'></td>
+ <td width='1' style='background-color: rgba(7,114,239,1)'></td>
+ <td width='1' style='background-color: rgba(8,111,241,1)'></td>
+ <td width='1' style='background-color: rgba(9,107,244,1)'></td>
+ <td width='1' style='background-color: rgba(9,104,246,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,103,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,107,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,110,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,112,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,114,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,114,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,114,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,111,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(169,90,88,1)'></td>
+ <td width='1' style='background-color: rgba(184,29,73,1)'></td>
+ <td width='1' style='background-color: rgba(174,29,139,1)'></td>
+ <td width='1' style='background-color: rgba(164,29,164,1)'></td>
+ <td width='1' style='background-color: rgba(153,29,183,1)'></td>
+ <td width='1' style='background-color: rgba(141,29,197,1)'></td>
+ <td width='1' style='background-color: rgba(127,29,211,1)'></td>
+ <td width='1' style='background-color: rgba(113,29,223,1)'></td>
+ <td width='1' style='background-color: rgba(94,29,234,1)'></td>
+ <td width='1' style='background-color: rgba(69,29,244,1)'></td>
+ <td width='1' style='background-color: rgba(3,29,254,1)'></td>
+ <td width='1' style='background-color: rgba(4,90,245,1)'></td>
+ <td width='1' style='background-color: rgba(4,105,241,1)'></td>
+ <td width='1' style='background-color: rgba(5,111,240,1)'></td>
+ <td width='1' style='background-color: rgba(5,114,238,1)'></td>
+ <td width='1' style='background-color: rgba(6,114,239,1)'></td>
+ <td width='1' style='background-color: rgba(7,114,240,1)'></td>
+ <td width='1' style='background-color: rgba(7,112,240,1)'></td>
+ <td width='1' style='background-color: rgba(8,110,243,1)'></td>
+ <td width='1' style='background-color: rgba(9,107,245,1)'></td>
+ <td width='1' style='background-color: rgba(9,103,247,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,103,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,106,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,108,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,109,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,110,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,109,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,107,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,100,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,87,105,1)'></td>
+ <td width='1' style='background-color: rgba(169,35,88,1)'></td>
+ <td width='1' style='background-color: rgba(161,35,143,1)'></td>
+ <td width='1' style='background-color: rgba(154,35,163,1)'></td>
+ <td width='1' style='background-color: rgba(147,35,179,1)'></td>
+ <td width='1' style='background-color: rgba(138,35,192,1)'></td>
+ <td width='1' style='background-color: rgba(129,35,203,1)'></td>
+ <td width='1' style='background-color: rgba(119,35,213,1)'></td>
+ <td width='1' style='background-color: rgba(108,35,222,1)'></td>
+ <td width='1' style='background-color: rgba(95,35,231,1)'></td>
+ <td width='1' style='background-color: rgba(79,35,238,1)'></td>
+ <td width='1' style='background-color: rgba(59,35,245,1)'></td>
+ <td width='1' style='background-color: rgba(4,35,253,1)'></td>
+ <td width='1' style='background-color: rgba(4,87,247,1)'></td>
+ <td width='1' style='background-color: rgba(5,100,244,1)'></td>
+ <td width='1' style='background-color: rgba(5,107,242,1)'></td>
+ <td width='1' style='background-color: rgba(6,109,241,1)'></td>
+ <td width='1' style='background-color: rgba(7,110,242,1)'></td>
+ <td width='1' style='background-color: rgba(7,109,242,1)'></td>
+ <td width='1' style='background-color: rgba(8,108,244,1)'></td>
+ <td width='1' style='background-color: rgba(9,106,246,1)'></td>
+ <td width='1' style='background-color: rgba(9,103,247,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,102,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,104,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,106,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,106,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,106,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,103,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,98,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,86,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,42,105,1)'></td>
+ <td width='1' style='background-color: rgba(146,42,150,1)'></td>
+ <td width='1' style='background-color: rgba(140,42,168,1)'></td>
+ <td width='1' style='background-color: rgba(135,42,181,1)'></td>
+ <td width='1' style='background-color: rgba(129,42,191,1)'></td>
+ <td width='1' style='background-color: rgba(122,42,200,1)'></td>
+ <td width='1' style='background-color: rgba(115,42,208,1)'></td>
+ <td width='1' style='background-color: rgba(107,42,216,1)'></td>
+ <td width='1' style='background-color: rgba(99,42,223,1)'></td>
+ <td width='1' style='background-color: rgba(90,42,230,1)'></td>
+ <td width='1' style='background-color: rgba(80,42,236,1)'></td>
+ <td width='1' style='background-color: rgba(67,42,241,1)'></td>
+ <td width='1' style='background-color: rgba(49,42,247,1)'></td>
+ <td width='1' style='background-color: rgba(4,42,253,1)'></td>
+ <td width='1' style='background-color: rgba(5,86,248,1)'></td>
+ <td width='1' style='background-color: rgba(5,98,245,1)'></td>
+ <td width='1' style='background-color: rgba(6,103,244,1)'></td>
+ <td width='1' style='background-color: rgba(7,106,244,1)'></td>
+ <td width='1' style='background-color: rgba(7,106,244,1)'></td>
+ <td width='1' style='background-color: rgba(8,106,245,1)'></td>
+ <td width='1' style='background-color: rgba(9,104,246,1)'></td>
+ <td width='1' style='background-color: rgba(9,102,247,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,102,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,103,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,104,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,103,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,101,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,96,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,86,137,1)'></td>
+ <td width='1' style='background-color: rgba(137,48,121,1)'></td>
+ <td width='1' style='background-color: rgba(132,48,159,1)'></td>
+ <td width='1' style='background-color: rgba(128,48,173,1)'></td>
+ <td width='1' style='background-color: rgba(124,48,184,1)'></td>
+ <td width='1' style='background-color: rgba(119,48,193,1)'></td>
+ <td width='1' style='background-color: rgba(114,48,201,1)'></td>
+ <td width='1' style='background-color: rgba(109,48,207,1)'></td>
+ <td width='1' style='background-color: rgba(104,48,214,1)'></td>
+ <td width='1' style='background-color: rgba(98,48,220,1)'></td>
+ <td width='1' style='background-color: rgba(91,48,225,1)'></td>
+ <td width='1' style='background-color: rgba(85,48,230,1)'></td>
+ <td width='1' style='background-color: rgba(77,48,235,1)'></td>
+ <td width='1' style='background-color: rgba(68,48,240,1)'></td>
+ <td width='1' style='background-color: rgba(57,48,244,1)'></td>
+ <td width='1' style='background-color: rgba(43,48,248,1)'></td>
+ <td width='1' style='background-color: rgba(5,48,253,1)'></td>
+ <td width='1' style='background-color: rgba(5,86,248,1)'></td>
+ <td width='1' style='background-color: rgba(6,96,246,1)'></td>
+ <td width='1' style='background-color: rgba(7,101,246,1)'></td>
+ <td width='1' style='background-color: rgba(7,103,245,1)'></td>
+ <td width='1' style='background-color: rgba(8,104,246,1)'></td>
+ <td width='1' style='background-color: rgba(9,103,247,1)'></td>
+ <td width='1' style='background-color: rgba(9,102,248,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,101,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,102,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,102,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,100,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,95,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,87,153,1)'></td>
+ <td width='1' style='background-color: rgba(120,55,137,1)'></td>
+ <td width='1' style='background-color: rgba(116,55,168,1)'></td>
+ <td width='1' style='background-color: rgba(113,55,180,1)'></td>
+ <td width='1' style='background-color: rgba(110,55,189,1)'></td>
+ <td width='1' style='background-color: rgba(106,55,196,1)'></td>
+ <td width='1' style='background-color: rgba(103,55,202,1)'></td>
+ <td width='1' style='background-color: rgba(99,55,208,1)'></td>
+ <td width='1' style='background-color: rgba(95,55,213,1)'></td>
+ <td width='1' style='background-color: rgba(91,55,218,1)'></td>
+ <td width='1' style='background-color: rgba(86,55,223,1)'></td>
+ <td width='1' style='background-color: rgba(81,55,227,1)'></td>
+ <td width='1' style='background-color: rgba(76,55,231,1)'></td>
+ <td width='1' style='background-color: rgba(70,55,235,1)'></td>
+ <td width='1' style='background-color: rgba(64,55,238,1)'></td>
+ <td width='1' style='background-color: rgba(57,55,242,1)'></td>
+ <td width='1' style='background-color: rgba(48,55,245,1)'></td>
+ <td width='1' style='background-color: rgba(36,55,248,1)'></td>
+ <td width='1' style='background-color: rgba(5,55,252,1)'></td>
+ <td width='1' style='background-color: rgba(6,87,249,1)'></td>
+ <td width='1' style='background-color: rgba(7,95,248,1)'></td>
+ <td width='1' style='background-color: rgba(7,100,246,1)'></td>
+ <td width='1' style='background-color: rgba(8,102,247,1)'></td>
+ <td width='1' style='background-color: rgba(9,102,248,1)'></td>
+ <td width='1' style='background-color: rgba(9,101,248,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,101,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,100,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,99,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,95,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,88,170,1)'></td>
+ <td width='1' style='background-color: rgba(105,61,153,1)'></td>
+ <td width='1' style='background-color: rgba(102,61,179,1)'></td>
+ <td width='1' style='background-color: rgba(99,61,188,1)'></td>
+ <td width='1' style='background-color: rgba(97,61,195,1)'></td>
+ <td width='1' style='background-color: rgba(94,61,201,1)'></td>
+ <td width='1' style='background-color: rgba(92,61,206,1)'></td>
+ <td width='1' style='background-color: rgba(89,61,211,1)'></td>
+ <td width='1' style='background-color: rgba(86,61,215,1)'></td>
+ <td width='1' style='background-color: rgba(83,61,219,1)'></td>
+ <td width='1' style='background-color: rgba(79,61,223,1)'></td>
+ <td width='1' style='background-color: rgba(76,61,226,1)'></td>
+ <td width='1' style='background-color: rgba(72,61,230,1)'></td>
+ <td width='1' style='background-color: rgba(68,61,233,1)'></td>
+ <td width='1' style='background-color: rgba(64,61,236,1)'></td>
+ <td width='1' style='background-color: rgba(59,61,239,1)'></td>
+ <td width='1' style='background-color: rgba(54,61,241,1)'></td>
+ <td width='1' style='background-color: rgba(48,61,244,1)'></td>
+ <td width='1' style='background-color: rgba(41,61,246,1)'></td>
+ <td width='1' style='background-color: rgba(32,61,249,1)'></td>
+ <td width='1' style='background-color: rgba(6,61,252,1)'></td>
+ <td width='1' style='background-color: rgba(7,88,250,1)'></td>
+ <td width='1' style='background-color: rgba(7,95,248,1)'></td>
+ <td width='1' style='background-color: rgba(8,99,248,1)'></td>
+ <td width='1' style='background-color: rgba(9,100,248,1)'></td>
+ <td width='1' style='background-color: rgba(9,101,248,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,100,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,99,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,96,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,89,185,1)'></td>
+ <td width='1' style='background-color: rgba(89,68,170,1)'></td>
+ <td width='1' style='background-color: rgba(87,68,190,1)'></td>
+ <td width='1' style='background-color: rgba(85,68,197,1)'></td>
+ <td width='1' style='background-color: rgba(83,68,203,1)'></td>
+ <td width='1' style='background-color: rgba(81,68,208,1)'></td>
+ <td width='1' style='background-color: rgba(79,68,212,1)'></td>
+ <td width='1' style='background-color: rgba(77,68,216,1)'></td>
+ <td width='1' style='background-color: rgba(75,68,219,1)'></td>
+ <td width='1' style='background-color: rgba(72,68,222,1)'></td>
+ <td width='1' style='background-color: rgba(70,68,225,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,228,1)'></td>
+ <td width='1' style='background-color: rgba(65,68,231,1)'></td>
+ <td width='1' style='background-color: rgba(62,68,233,1)'></td>
+ <td width='1' style='background-color: rgba(59,68,235,1)'></td>
+ <td width='1' style='background-color: rgba(56,68,238,1)'></td>
+ <td width='1' style='background-color: rgba(53,68,240,1)'></td>
+ <td width='1' style='background-color: rgba(49,68,242,1)'></td>
+ <td width='1' style='background-color: rgba(45,68,244,1)'></td>
+ <td width='1' style='background-color: rgba(40,68,246,1)'></td>
+ <td width='1' style='background-color: rgba(34,68,248,1)'></td>
+ <td width='1' style='background-color: rgba(27,68,250,1)'></td>
+ <td width='1' style='background-color: rgba(7,68,252,1)'></td>
+ <td width='1' style='background-color: rgba(7,89,249,1)'></td>
+ <td width='1' style='background-color: rgba(8,96,249,1)'></td>
+ <td width='1' style='background-color: rgba(9,99,249,1)'></td>
+ <td width='1' style='background-color: rgba(9,100,248,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,99,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,97,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,92,202,1)'></td>
+ <td width='1' style='background-color: rgba(73,74,185,1)'></td>
+ <td width='1' style='background-color: rgba(71,74,200,1)'></td>
+ <td width='1' style='background-color: rgba(70,74,206,1)'></td>
+ <td width='1' style='background-color: rgba(68,74,211,1)'></td>
+ <td width='1' style='background-color: rgba(67,74,214,1)'></td>
+ <td width='1' style='background-color: rgba(66,74,217,1)'></td>
+ <td width='1' style='background-color: rgba(64,74,220,1)'></td>
+ <td width='1' style='background-color: rgba(62,74,223,1)'></td>
+ <td width='1' style='background-color: rgba(61,74,225,1)'></td>
+ <td width='1' style='background-color: rgba(59,74,227,1)'></td>
+ <td width='1' style='background-color: rgba(57,74,230,1)'></td>
+ <td width='1' style='background-color: rgba(56,74,232,1)'></td>
+ <td width='1' style='background-color: rgba(54,74,234,1)'></td>
+ <td width='1' style='background-color: rgba(52,74,235,1)'></td>
+ <td width='1' style='background-color: rgba(49,74,237,1)'></td>
+ <td width='1' style='background-color: rgba(47,74,239,1)'></td>
+ <td width='1' style='background-color: rgba(45,74,240,1)'></td>
+ <td width='1' style='background-color: rgba(42,74,242,1)'></td>
+ <td width='1' style='background-color: rgba(39,74,244,1)'></td>
+ <td width='1' style='background-color: rgba(36,74,245,1)'></td>
+ <td width='1' style='background-color: rgba(33,74,246,1)'></td>
+ <td width='1' style='background-color: rgba(28,74,248,1)'></td>
+ <td width='1' style='background-color: rgba(22,74,249,1)'></td>
+ <td width='1' style='background-color: rgba(7,74,251,1)'></td>
+ <td width='1' style='background-color: rgba(8,92,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,97,249,1)'></td>
+ <td width='1' style='background-color: rgba(9,99,249,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,98,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,94,218,1)'></td>
+ <td width='1' style='background-color: rgba(57,81,202,1)'></td>
+ <td width='1' style='background-color: rgba(56,81,213,1)'></td>
+ <td width='1' style='background-color: rgba(55,81,217,1)'></td>
+ <td width='1' style='background-color: rgba(54,81,220,1)'></td>
+ <td width='1' style='background-color: rgba(53,81,223,1)'></td>
+ <td width='1' style='background-color: rgba(52,81,225,1)'></td>
+ <td width='1' style='background-color: rgba(51,81,227,1)'></td>
+ <td width='1' style='background-color: rgba(50,81,229,1)'></td>
+ <td width='1' style='background-color: rgba(49,81,231,1)'></td>
+ <td width='1' style='background-color: rgba(47,81,232,1)'></td>
+ <td width='1' style='background-color: rgba(46,81,234,1)'></td>
+ <td width='1' style='background-color: rgba(45,81,235,1)'></td>
+ <td width='1' style='background-color: rgba(44,81,237,1)'></td>
+ <td width='1' style='background-color: rgba(43,81,238,1)'></td>
+ <td width='1' style='background-color: rgba(41,81,239,1)'></td>
+ <td width='1' style='background-color: rgba(40,81,240,1)'></td>
+ <td width='1' style='background-color: rgba(38,81,241,1)'></td>
+ <td width='1' style='background-color: rgba(37,81,243,1)'></td>
+ <td width='1' style='background-color: rgba(35,81,244,1)'></td>
+ <td width='1' style='background-color: rgba(33,81,245,1)'></td>
+ <td width='1' style='background-color: rgba(31,81,246,1)'></td>
+ <td width='1' style='background-color: rgba(29,81,247,1)'></td>
+ <td width='1' style='background-color: rgba(26,81,248,1)'></td>
+ <td width='1' style='background-color: rgba(23,81,249,1)'></td>
+ <td width='1' style='background-color: rgba(19,81,250,1)'></td>
+ <td width='1' style='background-color: rgba(8,81,251,1)'></td>
+ <td width='1' style='background-color: rgba(9,94,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,98,249,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,97,234,1)'></td>
+ <td width='1' style='background-color: rgba(42,87,218,1)'></td>
+ <td width='1' style='background-color: rgba(41,87,225,1)'></td>
+ <td width='1' style='background-color: rgba(40,87,228,1)'></td>
+ <td width='1' style='background-color: rgba(40,87,230,1)'></td>
+ <td width='1' style='background-color: rgba(39,87,231,1)'></td>
+ <td width='1' style='background-color: rgba(39,87,233,1)'></td>
+ <td width='1' style='background-color: rgba(38,87,234,1)'></td>
+ <td width='1' style='background-color: rgba(37,87,235,1)'></td>
+ <td width='1' style='background-color: rgba(37,87,237,1)'></td>
+ <td width='1' style='background-color: rgba(36,87,238,1)'></td>
+ <td width='1' style='background-color: rgba(35,87,238,1)'></td>
+ <td width='1' style='background-color: rgba(35,87,240,1)'></td>
+ <td width='1' style='background-color: rgba(34,87,240,1)'></td>
+ <td width='1' style='background-color: rgba(33,87,241,1)'></td>
+ <td width='1' style='background-color: rgba(32,87,242,1)'></td>
+ <td width='1' style='background-color: rgba(31,87,243,1)'></td>
+ <td width='1' style='background-color: rgba(31,87,244,1)'></td>
+ <td width='1' style='background-color: rgba(29,87,244,1)'></td>
+ <td width='1' style='background-color: rgba(29,87,245,1)'></td>
+ <td width='1' style='background-color: rgba(28,87,246,1)'></td>
+ <td width='1' style='background-color: rgba(26,87,246,1)'></td>
+ <td width='1' style='background-color: rgba(25,87,247,1)'></td>
+ <td width='1' style='background-color: rgba(24,87,248,1)'></td>
+ <td width='1' style='background-color: rgba(22,87,248,1)'></td>
+ <td width='1' style='background-color: rgba(21,87,249,1)'></td>
+ <td width='1' style='background-color: rgba(19,87,249,1)'></td>
+ <td width='1' style='background-color: rgba(16,87,250,1)'></td>
+ <td width='1' style='background-color: rgba(9,87,251,1)'></td>
+ <td width='1' style='background-color: rgba(9,97,249,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(25,94,234,1)'></td>
+ <td width='1' style='background-color: rgba(24,94,237,1)'></td>
+ <td width='1' style='background-color: rgba(24,94,238,1)'></td>
+ <td width='1' style='background-color: rgba(24,94,239,1)'></td>
+ <td width='1' style='background-color: rgba(23,94,240,1)'></td>
+ <td width='1' style='background-color: rgba(23,94,241,1)'></td>
+ <td width='1' style='background-color: rgba(23,94,241,1)'></td>
+ <td width='1' style='background-color: rgba(23,94,242,1)'></td>
+ <td width='1' style='background-color: rgba(22,94,242,1)'></td>
+ <td width='1' style='background-color: rgba(22,94,243,1)'></td>
+ <td width='1' style='background-color: rgba(22,94,243,1)'></td>
+ <td width='1' style='background-color: rgba(21,94,244,1)'></td>
+ <td width='1' style='background-color: rgba(21,94,244,1)'></td>
+ <td width='1' style='background-color: rgba(21,94,245,1)'></td>
+ <td width='1' style='background-color: rgba(20,94,245,1)'></td>
+ <td width='1' style='background-color: rgba(20,94,245,1)'></td>
+ <td width='1' style='background-color: rgba(20,94,246,1)'></td>
+ <td width='1' style='background-color: rgba(19,94,246,1)'></td>
+ <td width='1' style='background-color: rgba(19,94,246,1)'></td>
+ <td width='1' style='background-color: rgba(18,94,247,1)'></td>
+ <td width='1' style='background-color: rgba(18,94,247,1)'></td>
+ <td width='1' style='background-color: rgba(17,94,247,1)'></td>
+ <td width='1' style='background-color: rgba(17,94,248,1)'></td>
+ <td width='1' style='background-color: rgba(16,94,248,1)'></td>
+ <td width='1' style='background-color: rgba(16,94,248,1)'></td>
+ <td width='1' style='background-color: rgba(15,94,248,1)'></td>
+ <td width='1' style='background-color: rgba(14,94,249,1)'></td>
+ <td width='1' style='background-color: rgba(13,94,249,1)'></td>
+ <td width='1' style='background-color: rgba(12,94,249,1)'></td>
+ <td width='1' style='background-color: rgba(9,94,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+ <td width='1' style='background-color: rgba(10,100,250,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-background/bgai4a08.png b/image/test/reftest/pngsuite-background/bgai4a08.png
new file mode 100644
index 0000000000..398132be5f
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/bgai4a08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-background/bgai4a16.png b/image/test/reftest/pngsuite-background/bgai4a16.png
new file mode 100644
index 0000000000..51192e7311
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/bgai4a16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-background/bgan6a08.png b/image/test/reftest/pngsuite-background/bgan6a08.png
new file mode 100644
index 0000000000..e608738763
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/bgan6a08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-background/bgan6a16.png b/image/test/reftest/pngsuite-background/bgan6a16.png
new file mode 100644
index 0000000000..984a99525f
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/bgan6a16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-background/bgbn4a08.png b/image/test/reftest/pngsuite-background/bgbn4a08.png
new file mode 100644
index 0000000000..7cbefc3bff
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/bgbn4a08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-background/bggn4a16.png b/image/test/reftest/pngsuite-background/bggn4a16.png
new file mode 100644
index 0000000000..13fd85ba19
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/bggn4a16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-background/bgwn6a08.png b/image/test/reftest/pngsuite-background/bgwn6a08.png
new file mode 100644
index 0000000000..a67ff205bb
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/bgwn6a08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-background/bgyn6a16.png b/image/test/reftest/pngsuite-background/bgyn6a16.png
new file mode 100644
index 0000000000..ae3e9be58a
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/bgyn6a16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-background/reftest.list b/image/test/reftest/pngsuite-background/reftest.list
new file mode 100644
index 0000000000..1b6c514de1
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/reftest.list
@@ -0,0 +1,22 @@
+# PngSuite - Background colors
+#
+# Note 1: The first 4 images have no bKGD chunk, the last 4 do. The background
+# color indicated by bKGD isn't used, so the two sets of images are rendered
+# identically and thus share common reference HTML files.
+
+# bgai4a08 - 8 bit grayscale, alpha, no background chunk, interlaced
+fuzzy(0-2,0-1024) == wrapper.html?bgai4a08.png bg__4a08.html
+# bgai4a16 - 16 bit grayscale, alpha, no background chunk, interlaced
+fuzzy(0-2,0-1024) == wrapper.html?bgai4a16.png bg__4a16.html
+# bgan6a08 - 3x8 bits rgb color, alpha, no background chunk
+fuzzy(0-2,0-1024) == wrapper.html?bgan6a08.png bg__6a08.html
+# bgan6a16 - 3x16 bits rgb color, alpha, no background chunk
+fuzzy(0-2,0-1024) == wrapper.html?bgan6a16.png bg__6a16.html
+# bgbn4a08 - 8 bit grayscale, alpha, black background chunk
+fuzzy(0-2,0-1024) == wrapper.html?bgbn4a08.png bg__4a08.html
+# bggn4a16 - 16 bit grayscale, alpha, gray background chunk
+fuzzy(0-2,0-1024) == wrapper.html?bggn4a16.png bg__4a16.html
+# bgwn6a08 - 3x8 bits rgb color, alpha, white background chunk
+fuzzy(0-2,0-1024) == wrapper.html?bgwn6a08.png bg__6a08.html
+# bgyn6a16 - 3x16 bits rgb color, alpha, yellow background chunk
+fuzzy(0-2,0-1024) == wrapper.html?bgyn6a16.png bg__6a16.html
diff --git a/image/test/reftest/pngsuite-background/wrapper.html b/image/test/reftest/pngsuite-background/wrapper.html
new file mode 100644
index 0000000000..45b5167754
--- /dev/null
+++ b/image/test/reftest/pngsuite-background/wrapper.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Image reftest wrapper</title>
+<style type="text/css">
+ #image1 { background-color: rgb(10, 100, 250); }
+</style>
+<script>
+ // The image is loaded async after the page loads
+ // wait for it to finish loading
+ function onImageLoad() {
+ document.documentElement.removeAttribute("class");
+ };
+</script>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img id="image1" alt=" ">
+<script>
+ // Use as "wrapper.html?image.png
+ var imgURL = document.location.search.substr(1);
+ document.images[0].onload = onImageLoad;
+ document.images[0].onerror = onImageLoad;
+ document.images[0].src = imgURL;
+</script>
+</body>
+</html>
+
diff --git a/image/test/reftest/pngsuite-basic-i/basi0g01.html b/image/test/reftest/pngsuite-basic-i/basi0g01.html
new file mode 100644
index 0000000000..7389a1b66e
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi0g01.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-i/basi0g01.png b/image/test/reftest/pngsuite-basic-i/basi0g01.png
new file mode 100644
index 0000000000..556fa72704
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi0g01.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi0g02.html b/image/test/reftest/pngsuite-basic-i/basi0g02.html
new file mode 100644
index 0000000000..538afad142
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi0g02.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-i/basi0g02.png b/image/test/reftest/pngsuite-basic-i/basi0g02.png
new file mode 100644
index 0000000000..ce09821ef1
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi0g02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi0g04.html b/image/test/reftest/pngsuite-basic-i/basi0g04.html
new file mode 100644
index 0000000000..d782230d4b
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi0g04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-i/basi0g04.png b/image/test/reftest/pngsuite-basic-i/basi0g04.png
new file mode 100644
index 0000000000..3853273f93
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi0g04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi0g08.html b/image/test/reftest/pngsuite-basic-i/basi0g08.html
new file mode 100644
index 0000000000..5aaf11cabb
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi0g08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-i/basi0g08.png b/image/test/reftest/pngsuite-basic-i/basi0g08.png
new file mode 100644
index 0000000000..faed8bec44
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi0g08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi0g16.html b/image/test/reftest/pngsuite-basic-i/basi0g16.html
new file mode 100644
index 0000000000..fc18c727be
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi0g16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(104,104,104,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(83,83,83,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,100,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(108,108,108,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(104,104,104,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(83,83,83,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,100,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(108,108,108,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(104,104,104,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(97,97,97,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(65,65,65,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(49,49,49,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-i/basi0g16.png b/image/test/reftest/pngsuite-basic-i/basi0g16.png
new file mode 100644
index 0000000000..a9f28165ef
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi0g16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi2c08.html b/image/test/reftest/pngsuite-basic-i/basi2c08.html
new file mode 100644
index 0000000000..e30216bdf0
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,253,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,253,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,252,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,252,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,249,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,249,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,249,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,245,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,245,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,244,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,244,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,243,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,243,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,241,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,241,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,237,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,237,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,236,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,236,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,235,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,235,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,233,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,233,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,232,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,232,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,226,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,226,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,225,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,225,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,222,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,220,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,220,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,218,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,218,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,217,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,217,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,216,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,214,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,214,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,213,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,213,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,211,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,210,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,210,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,209,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,209,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,208,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,205,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,205,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,203,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,203,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,201,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,200,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,200,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,197,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,197,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,195,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,195,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,194,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,194,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,193,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,190,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,190,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,189,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,188,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,188,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,185,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,184,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,184,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,182,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,182,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,181,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,179,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,178,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,178,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,177,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,176,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,172,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,171,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,170,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,170,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,169,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,165,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,164,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,162,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,161,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,160,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,160,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,157,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,156,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,156,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,154,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,153,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,152,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,149,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,148,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,147,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,146,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,145,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,141,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,139,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,138,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,137,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,136,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,133,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,132,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,129,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,128,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,122,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,120,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,116,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,114,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,112,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,107,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,106,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,99,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,96,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,92,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,90,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,84,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,82,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,80,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,76,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,72,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,70,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,68,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,66,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,64,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,59,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,56,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,50,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,43,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,34,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,28,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,253,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,253,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,252,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,252,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,249,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,249,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,249,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,248,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,248,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,244,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,244,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,237,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,237,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,225,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,225,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,220,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,220,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,216,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,215,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,215,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,210,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,210,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,207,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,207,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,201,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,200,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,200,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,196,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,195,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,195,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,191,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,190,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,190,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,187,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,185,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,184,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,184,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,181,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,179,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,176,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,175,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,175,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,170,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,170,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,169,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,167,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,167,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,161,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,160,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,160,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,158,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,157,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,153,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,150,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,149,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,148,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,147,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,143,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,142,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,141,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,135,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,134,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,133,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,132,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,128,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,127,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,126,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,125,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,124,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,122,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,119,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,118,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,117,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,116,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,114,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,112,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,110,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,109,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,107,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,106,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,103,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,98,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,96,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,95,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,93,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,92,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,90,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,85,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,84,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,82,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,80,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,78,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,76,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,72,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,70,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,68,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,66,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,64,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,61,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,59,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,56,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,50,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,46,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,43,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,39,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,34,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,28,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(253,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(253,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(252,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(252,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(249,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(249,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(249,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(248,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(248,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(245,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(245,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(244,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(244,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(241,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(241,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(237,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(237,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(233,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(233,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(229,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(229,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(225,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(225,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(224,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(223,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(223,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(220,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(220,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(217,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(217,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(216,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(215,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(215,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(211,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(210,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(210,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(207,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(207,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(206,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(201,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(200,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(200,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(196,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(195,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(195,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(191,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(187,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(186,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(185,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(184,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(184,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(182,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(182,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(179,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(176,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(175,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(175,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(174,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(170,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(170,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(167,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(167,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(163,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(162,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(161,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(160,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(160,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(158,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(157,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(154,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(153,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(151,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(151,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(150,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(149,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(148,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(146,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(143,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(142,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(141,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(139,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(135,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(134,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(133,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(131,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(130,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(128,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(127,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(126,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(124,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(122,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(119,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(118,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(117,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(116,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(115,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(114,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(112,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(110,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(107,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(106,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(103,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(98,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(95,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(93,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(89,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(85,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(80,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(78,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(72,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(70,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(66,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(64,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(61,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(56,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(46,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(39,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(28,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-i/basi2c08.png b/image/test/reftest/pngsuite-basic-i/basi2c08.png
new file mode 100644
index 0000000000..2aab44d42b
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi2c16.html b/image/test/reftest/pngsuite-basic-i/basi2c16.html
new file mode 100644
index 0000000000..dd08f0e3d0
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi2c16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,251,53,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,247,53,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,73,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,243,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,243,73,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,88,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,239,53,1)'></td>
+ <td width='1' style='background-color: rgba(73,239,73,1)'></td>
+ <td width='1' style='background-color: rgba(53,239,88,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,100,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,235,53,1)'></td>
+ <td width='1' style='background-color: rgba(88,235,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,235,88,1)'></td>
+ <td width='1' style='background-color: rgba(53,235,100,1)'></td>
+ <td width='1' style='background-color: rgba(0,235,111,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,231,53,1)'></td>
+ <td width='1' style='background-color: rgba(100,231,73,1)'></td>
+ <td width='1' style='background-color: rgba(88,231,88,1)'></td>
+ <td width='1' style='background-color: rgba(73,231,100,1)'></td>
+ <td width='1' style='background-color: rgba(53,231,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,231,121,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,227,53,1)'></td>
+ <td width='1' style='background-color: rgba(111,227,73,1)'></td>
+ <td width='1' style='background-color: rgba(100,227,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,227,100,1)'></td>
+ <td width='1' style='background-color: rgba(73,227,111,1)'></td>
+ <td width='1' style='background-color: rgba(53,227,121,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,130,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,223,53,1)'></td>
+ <td width='1' style='background-color: rgba(121,223,73,1)'></td>
+ <td width='1' style='background-color: rgba(111,223,88,1)'></td>
+ <td width='1' style='background-color: rgba(100,223,100,1)'></td>
+ <td width='1' style='background-color: rgba(88,223,111,1)'></td>
+ <td width='1' style='background-color: rgba(73,223,121,1)'></td>
+ <td width='1' style='background-color: rgba(53,223,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,223,138,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,218,53,1)'></td>
+ <td width='1' style='background-color: rgba(130,218,73,1)'></td>
+ <td width='1' style='background-color: rgba(121,218,88,1)'></td>
+ <td width='1' style='background-color: rgba(111,218,100,1)'></td>
+ <td width='1' style='background-color: rgba(100,218,111,1)'></td>
+ <td width='1' style='background-color: rgba(88,218,121,1)'></td>
+ <td width='1' style='background-color: rgba(73,218,130,1)'></td>
+ <td width='1' style='background-color: rgba(53,218,138,1)'></td>
+ <td width='1' style='background-color: rgba(0,218,145,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,214,53,1)'></td>
+ <td width='1' style='background-color: rgba(138,214,73,1)'></td>
+ <td width='1' style='background-color: rgba(130,214,88,1)'></td>
+ <td width='1' style='background-color: rgba(121,214,100,1)'></td>
+ <td width='1' style='background-color: rgba(111,214,111,1)'></td>
+ <td width='1' style='background-color: rgba(100,214,121,1)'></td>
+ <td width='1' style='background-color: rgba(88,214,130,1)'></td>
+ <td width='1' style='background-color: rgba(73,214,138,1)'></td>
+ <td width='1' style='background-color: rgba(53,214,145,1)'></td>
+ <td width='1' style='background-color: rgba(0,214,152,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,209,53,1)'></td>
+ <td width='1' style='background-color: rgba(145,209,73,1)'></td>
+ <td width='1' style='background-color: rgba(138,209,88,1)'></td>
+ <td width='1' style='background-color: rgba(130,209,100,1)'></td>
+ <td width='1' style='background-color: rgba(121,209,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,209,121,1)'></td>
+ <td width='1' style='background-color: rgba(100,209,130,1)'></td>
+ <td width='1' style='background-color: rgba(88,209,138,1)'></td>
+ <td width='1' style='background-color: rgba(73,209,145,1)'></td>
+ <td width='1' style='background-color: rgba(53,209,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,159,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,204,53,1)'></td>
+ <td width='1' style='background-color: rgba(152,204,73,1)'></td>
+ <td width='1' style='background-color: rgba(145,204,88,1)'></td>
+ <td width='1' style='background-color: rgba(138,204,100,1)'></td>
+ <td width='1' style='background-color: rgba(130,204,111,1)'></td>
+ <td width='1' style='background-color: rgba(121,204,121,1)'></td>
+ <td width='1' style='background-color: rgba(111,204,130,1)'></td>
+ <td width='1' style='background-color: rgba(100,204,138,1)'></td>
+ <td width='1' style='background-color: rgba(88,204,145,1)'></td>
+ <td width='1' style='background-color: rgba(73,204,152,1)'></td>
+ <td width='1' style='background-color: rgba(53,204,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,204,166,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,199,53,1)'></td>
+ <td width='1' style='background-color: rgba(159,199,73,1)'></td>
+ <td width='1' style='background-color: rgba(152,199,88,1)'></td>
+ <td width='1' style='background-color: rgba(145,199,100,1)'></td>
+ <td width='1' style='background-color: rgba(138,199,111,1)'></td>
+ <td width='1' style='background-color: rgba(130,199,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,199,130,1)'></td>
+ <td width='1' style='background-color: rgba(111,199,138,1)'></td>
+ <td width='1' style='background-color: rgba(100,199,145,1)'></td>
+ <td width='1' style='background-color: rgba(88,199,152,1)'></td>
+ <td width='1' style='background-color: rgba(73,199,159,1)'></td>
+ <td width='1' style='background-color: rgba(53,199,166,1)'></td>
+ <td width='1' style='background-color: rgba(0,199,172,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,194,53,1)'></td>
+ <td width='1' style='background-color: rgba(166,194,73,1)'></td>
+ <td width='1' style='background-color: rgba(159,194,88,1)'></td>
+ <td width='1' style='background-color: rgba(152,194,100,1)'></td>
+ <td width='1' style='background-color: rgba(145,194,111,1)'></td>
+ <td width='1' style='background-color: rgba(138,194,121,1)'></td>
+ <td width='1' style='background-color: rgba(130,194,130,1)'></td>
+ <td width='1' style='background-color: rgba(121,194,138,1)'></td>
+ <td width='1' style='background-color: rgba(111,194,145,1)'></td>
+ <td width='1' style='background-color: rgba(100,194,152,1)'></td>
+ <td width='1' style='background-color: rgba(88,194,159,1)'></td>
+ <td width='1' style='background-color: rgba(73,194,166,1)'></td>
+ <td width='1' style='background-color: rgba(53,194,172,1)'></td>
+ <td width='1' style='background-color: rgba(0,194,178,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,189,53,1)'></td>
+ <td width='1' style='background-color: rgba(172,189,73,1)'></td>
+ <td width='1' style='background-color: rgba(166,189,88,1)'></td>
+ <td width='1' style='background-color: rgba(159,189,100,1)'></td>
+ <td width='1' style='background-color: rgba(152,189,111,1)'></td>
+ <td width='1' style='background-color: rgba(145,189,121,1)'></td>
+ <td width='1' style='background-color: rgba(138,189,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,189,138,1)'></td>
+ <td width='1' style='background-color: rgba(121,189,145,1)'></td>
+ <td width='1' style='background-color: rgba(111,189,152,1)'></td>
+ <td width='1' style='background-color: rgba(100,189,159,1)'></td>
+ <td width='1' style='background-color: rgba(88,189,166,1)'></td>
+ <td width='1' style='background-color: rgba(73,189,172,1)'></td>
+ <td width='1' style='background-color: rgba(53,189,178,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,183,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,53,1)'></td>
+ <td width='1' style='background-color: rgba(178,183,73,1)'></td>
+ <td width='1' style='background-color: rgba(172,183,88,1)'></td>
+ <td width='1' style='background-color: rgba(166,183,100,1)'></td>
+ <td width='1' style='background-color: rgba(159,183,111,1)'></td>
+ <td width='1' style='background-color: rgba(152,183,121,1)'></td>
+ <td width='1' style='background-color: rgba(145,183,130,1)'></td>
+ <td width='1' style='background-color: rgba(138,183,138,1)'></td>
+ <td width='1' style='background-color: rgba(130,183,145,1)'></td>
+ <td width='1' style='background-color: rgba(121,183,152,1)'></td>
+ <td width='1' style='background-color: rgba(111,183,159,1)'></td>
+ <td width='1' style='background-color: rgba(100,183,166,1)'></td>
+ <td width='1' style='background-color: rgba(88,183,172,1)'></td>
+ <td width='1' style='background-color: rgba(73,183,178,1)'></td>
+ <td width='1' style='background-color: rgba(53,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,183,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,178,53,1)'></td>
+ <td width='1' style='background-color: rgba(183,178,73,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,88,1)'></td>
+ <td width='1' style='background-color: rgba(172,178,100,1)'></td>
+ <td width='1' style='background-color: rgba(166,178,111,1)'></td>
+ <td width='1' style='background-color: rgba(159,178,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,178,130,1)'></td>
+ <td width='1' style='background-color: rgba(145,178,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,178,145,1)'></td>
+ <td width='1' style='background-color: rgba(130,178,152,1)'></td>
+ <td width='1' style='background-color: rgba(121,178,159,1)'></td>
+ <td width='1' style='background-color: rgba(111,178,166,1)'></td>
+ <td width='1' style='background-color: rgba(100,178,172,1)'></td>
+ <td width='1' style='background-color: rgba(88,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(73,178,183,1)'></td>
+ <td width='1' style='background-color: rgba(53,178,189,1)'></td>
+ <td width='1' style='background-color: rgba(0,178,194,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,172,53,1)'></td>
+ <td width='1' style='background-color: rgba(189,172,73,1)'></td>
+ <td width='1' style='background-color: rgba(183,172,88,1)'></td>
+ <td width='1' style='background-color: rgba(178,172,100,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,111,1)'></td>
+ <td width='1' style='background-color: rgba(166,172,121,1)'></td>
+ <td width='1' style='background-color: rgba(159,172,130,1)'></td>
+ <td width='1' style='background-color: rgba(152,172,138,1)'></td>
+ <td width='1' style='background-color: rgba(145,172,145,1)'></td>
+ <td width='1' style='background-color: rgba(138,172,152,1)'></td>
+ <td width='1' style='background-color: rgba(130,172,159,1)'></td>
+ <td width='1' style='background-color: rgba(121,172,166,1)'></td>
+ <td width='1' style='background-color: rgba(111,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(100,172,178,1)'></td>
+ <td width='1' style='background-color: rgba(88,172,183,1)'></td>
+ <td width='1' style='background-color: rgba(73,172,189,1)'></td>
+ <td width='1' style='background-color: rgba(53,172,194,1)'></td>
+ <td width='1' style='background-color: rgba(0,172,199,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,166,53,1)'></td>
+ <td width='1' style='background-color: rgba(194,166,73,1)'></td>
+ <td width='1' style='background-color: rgba(189,166,88,1)'></td>
+ <td width='1' style='background-color: rgba(183,166,100,1)'></td>
+ <td width='1' style='background-color: rgba(178,166,111,1)'></td>
+ <td width='1' style='background-color: rgba(172,166,121,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,130,1)'></td>
+ <td width='1' style='background-color: rgba(159,166,138,1)'></td>
+ <td width='1' style='background-color: rgba(152,166,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,166,152,1)'></td>
+ <td width='1' style='background-color: rgba(138,166,159,1)'></td>
+ <td width='1' style='background-color: rgba(130,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(121,166,172,1)'></td>
+ <td width='1' style='background-color: rgba(111,166,178,1)'></td>
+ <td width='1' style='background-color: rgba(100,166,183,1)'></td>
+ <td width='1' style='background-color: rgba(88,166,189,1)'></td>
+ <td width='1' style='background-color: rgba(73,166,194,1)'></td>
+ <td width='1' style='background-color: rgba(53,166,199,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,204,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,159,53,1)'></td>
+ <td width='1' style='background-color: rgba(199,159,73,1)'></td>
+ <td width='1' style='background-color: rgba(194,159,88,1)'></td>
+ <td width='1' style='background-color: rgba(189,159,100,1)'></td>
+ <td width='1' style='background-color: rgba(183,159,111,1)'></td>
+ <td width='1' style='background-color: rgba(178,159,121,1)'></td>
+ <td width='1' style='background-color: rgba(172,159,130,1)'></td>
+ <td width='1' style='background-color: rgba(166,159,138,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,145,1)'></td>
+ <td width='1' style='background-color: rgba(152,159,152,1)'></td>
+ <td width='1' style='background-color: rgba(145,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(138,159,166,1)'></td>
+ <td width='1' style='background-color: rgba(130,159,172,1)'></td>
+ <td width='1' style='background-color: rgba(121,159,178,1)'></td>
+ <td width='1' style='background-color: rgba(111,159,183,1)'></td>
+ <td width='1' style='background-color: rgba(100,159,189,1)'></td>
+ <td width='1' style='background-color: rgba(88,159,194,1)'></td>
+ <td width='1' style='background-color: rgba(73,159,199,1)'></td>
+ <td width='1' style='background-color: rgba(53,159,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,159,209,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,152,53,1)'></td>
+ <td width='1' style='background-color: rgba(204,152,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,152,88,1)'></td>
+ <td width='1' style='background-color: rgba(194,152,100,1)'></td>
+ <td width='1' style='background-color: rgba(189,152,111,1)'></td>
+ <td width='1' style='background-color: rgba(183,152,121,1)'></td>
+ <td width='1' style='background-color: rgba(178,152,130,1)'></td>
+ <td width='1' style='background-color: rgba(172,152,138,1)'></td>
+ <td width='1' style='background-color: rgba(166,152,145,1)'></td>
+ <td width='1' style='background-color: rgba(159,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,159,1)'></td>
+ <td width='1' style='background-color: rgba(145,152,166,1)'></td>
+ <td width='1' style='background-color: rgba(138,152,172,1)'></td>
+ <td width='1' style='background-color: rgba(130,152,178,1)'></td>
+ <td width='1' style='background-color: rgba(121,152,183,1)'></td>
+ <td width='1' style='background-color: rgba(111,152,189,1)'></td>
+ <td width='1' style='background-color: rgba(100,152,194,1)'></td>
+ <td width='1' style='background-color: rgba(88,152,199,1)'></td>
+ <td width='1' style='background-color: rgba(73,152,204,1)'></td>
+ <td width='1' style='background-color: rgba(53,152,209,1)'></td>
+ <td width='1' style='background-color: rgba(0,152,214,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,145,53,1)'></td>
+ <td width='1' style='background-color: rgba(209,145,73,1)'></td>
+ <td width='1' style='background-color: rgba(204,145,88,1)'></td>
+ <td width='1' style='background-color: rgba(199,145,100,1)'></td>
+ <td width='1' style='background-color: rgba(194,145,111,1)'></td>
+ <td width='1' style='background-color: rgba(189,145,121,1)'></td>
+ <td width='1' style='background-color: rgba(183,145,130,1)'></td>
+ <td width='1' style='background-color: rgba(178,145,138,1)'></td>
+ <td width='1' style='background-color: rgba(172,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(166,145,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,145,159,1)'></td>
+ <td width='1' style='background-color: rgba(152,145,166,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,172,1)'></td>
+ <td width='1' style='background-color: rgba(138,145,178,1)'></td>
+ <td width='1' style='background-color: rgba(130,145,183,1)'></td>
+ <td width='1' style='background-color: rgba(121,145,189,1)'></td>
+ <td width='1' style='background-color: rgba(111,145,194,1)'></td>
+ <td width='1' style='background-color: rgba(100,145,199,1)'></td>
+ <td width='1' style='background-color: rgba(88,145,204,1)'></td>
+ <td width='1' style='background-color: rgba(73,145,209,1)'></td>
+ <td width='1' style='background-color: rgba(53,145,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,218,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,138,53,1)'></td>
+ <td width='1' style='background-color: rgba(214,138,73,1)'></td>
+ <td width='1' style='background-color: rgba(209,138,88,1)'></td>
+ <td width='1' style='background-color: rgba(204,138,100,1)'></td>
+ <td width='1' style='background-color: rgba(199,138,111,1)'></td>
+ <td width='1' style='background-color: rgba(194,138,121,1)'></td>
+ <td width='1' style='background-color: rgba(189,138,130,1)'></td>
+ <td width='1' style='background-color: rgba(183,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(178,138,145,1)'></td>
+ <td width='1' style='background-color: rgba(172,138,152,1)'></td>
+ <td width='1' style='background-color: rgba(166,138,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,138,166,1)'></td>
+ <td width='1' style='background-color: rgba(152,138,172,1)'></td>
+ <td width='1' style='background-color: rgba(145,138,178,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,183,1)'></td>
+ <td width='1' style='background-color: rgba(130,138,189,1)'></td>
+ <td width='1' style='background-color: rgba(121,138,194,1)'></td>
+ <td width='1' style='background-color: rgba(111,138,199,1)'></td>
+ <td width='1' style='background-color: rgba(100,138,204,1)'></td>
+ <td width='1' style='background-color: rgba(88,138,209,1)'></td>
+ <td width='1' style='background-color: rgba(73,138,214,1)'></td>
+ <td width='1' style='background-color: rgba(53,138,218,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,130,53,1)'></td>
+ <td width='1' style='background-color: rgba(218,130,73,1)'></td>
+ <td width='1' style='background-color: rgba(214,130,88,1)'></td>
+ <td width='1' style='background-color: rgba(209,130,100,1)'></td>
+ <td width='1' style='background-color: rgba(204,130,111,1)'></td>
+ <td width='1' style='background-color: rgba(199,130,121,1)'></td>
+ <td width='1' style='background-color: rgba(194,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(189,130,138,1)'></td>
+ <td width='1' style='background-color: rgba(183,130,145,1)'></td>
+ <td width='1' style='background-color: rgba(178,130,152,1)'></td>
+ <td width='1' style='background-color: rgba(172,130,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,130,166,1)'></td>
+ <td width='1' style='background-color: rgba(159,130,172,1)'></td>
+ <td width='1' style='background-color: rgba(152,130,178,1)'></td>
+ <td width='1' style='background-color: rgba(145,130,183,1)'></td>
+ <td width='1' style='background-color: rgba(138,130,189,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,194,1)'></td>
+ <td width='1' style='background-color: rgba(121,130,199,1)'></td>
+ <td width='1' style='background-color: rgba(111,130,204,1)'></td>
+ <td width='1' style='background-color: rgba(100,130,209,1)'></td>
+ <td width='1' style='background-color: rgba(88,130,214,1)'></td>
+ <td width='1' style='background-color: rgba(73,130,218,1)'></td>
+ <td width='1' style='background-color: rgba(53,130,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,130,227,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,121,53,1)'></td>
+ <td width='1' style='background-color: rgba(223,121,73,1)'></td>
+ <td width='1' style='background-color: rgba(218,121,88,1)'></td>
+ <td width='1' style='background-color: rgba(214,121,100,1)'></td>
+ <td width='1' style='background-color: rgba(209,121,111,1)'></td>
+ <td width='1' style='background-color: rgba(204,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(199,121,130,1)'></td>
+ <td width='1' style='background-color: rgba(194,121,138,1)'></td>
+ <td width='1' style='background-color: rgba(189,121,145,1)'></td>
+ <td width='1' style='background-color: rgba(183,121,152,1)'></td>
+ <td width='1' style='background-color: rgba(178,121,159,1)'></td>
+ <td width='1' style='background-color: rgba(172,121,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,121,172,1)'></td>
+ <td width='1' style='background-color: rgba(159,121,178,1)'></td>
+ <td width='1' style='background-color: rgba(152,121,183,1)'></td>
+ <td width='1' style='background-color: rgba(145,121,189,1)'></td>
+ <td width='1' style='background-color: rgba(138,121,194,1)'></td>
+ <td width='1' style='background-color: rgba(130,121,199,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,204,1)'></td>
+ <td width='1' style='background-color: rgba(111,121,209,1)'></td>
+ <td width='1' style='background-color: rgba(100,121,214,1)'></td>
+ <td width='1' style='background-color: rgba(88,121,218,1)'></td>
+ <td width='1' style='background-color: rgba(73,121,223,1)'></td>
+ <td width='1' style='background-color: rgba(53,121,227,1)'></td>
+ <td width='1' style='background-color: rgba(0,121,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,111,53,1)'></td>
+ <td width='1' style='background-color: rgba(227,111,73,1)'></td>
+ <td width='1' style='background-color: rgba(223,111,88,1)'></td>
+ <td width='1' style='background-color: rgba(218,111,100,1)'></td>
+ <td width='1' style='background-color: rgba(214,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(209,111,121,1)'></td>
+ <td width='1' style='background-color: rgba(204,111,130,1)'></td>
+ <td width='1' style='background-color: rgba(199,111,138,1)'></td>
+ <td width='1' style='background-color: rgba(194,111,145,1)'></td>
+ <td width='1' style='background-color: rgba(189,111,152,1)'></td>
+ <td width='1' style='background-color: rgba(183,111,159,1)'></td>
+ <td width='1' style='background-color: rgba(178,111,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,111,172,1)'></td>
+ <td width='1' style='background-color: rgba(166,111,178,1)'></td>
+ <td width='1' style='background-color: rgba(159,111,183,1)'></td>
+ <td width='1' style='background-color: rgba(152,111,189,1)'></td>
+ <td width='1' style='background-color: rgba(145,111,194,1)'></td>
+ <td width='1' style='background-color: rgba(138,111,199,1)'></td>
+ <td width='1' style='background-color: rgba(130,111,204,1)'></td>
+ <td width='1' style='background-color: rgba(121,111,209,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,214,1)'></td>
+ <td width='1' style='background-color: rgba(100,111,218,1)'></td>
+ <td width='1' style='background-color: rgba(88,111,223,1)'></td>
+ <td width='1' style='background-color: rgba(73,111,227,1)'></td>
+ <td width='1' style='background-color: rgba(53,111,231,1)'></td>
+ <td width='1' style='background-color: rgba(0,111,235,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,100,53,1)'></td>
+ <td width='1' style='background-color: rgba(231,100,73,1)'></td>
+ <td width='1' style='background-color: rgba(227,100,88,1)'></td>
+ <td width='1' style='background-color: rgba(223,100,100,1)'></td>
+ <td width='1' style='background-color: rgba(218,100,111,1)'></td>
+ <td width='1' style='background-color: rgba(214,100,121,1)'></td>
+ <td width='1' style='background-color: rgba(209,100,130,1)'></td>
+ <td width='1' style='background-color: rgba(204,100,138,1)'></td>
+ <td width='1' style='background-color: rgba(199,100,145,1)'></td>
+ <td width='1' style='background-color: rgba(194,100,152,1)'></td>
+ <td width='1' style='background-color: rgba(189,100,159,1)'></td>
+ <td width='1' style='background-color: rgba(183,100,166,1)'></td>
+ <td width='1' style='background-color: rgba(178,100,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,100,178,1)'></td>
+ <td width='1' style='background-color: rgba(166,100,183,1)'></td>
+ <td width='1' style='background-color: rgba(159,100,189,1)'></td>
+ <td width='1' style='background-color: rgba(152,100,194,1)'></td>
+ <td width='1' style='background-color: rgba(145,100,199,1)'></td>
+ <td width='1' style='background-color: rgba(138,100,204,1)'></td>
+ <td width='1' style='background-color: rgba(130,100,209,1)'></td>
+ <td width='1' style='background-color: rgba(121,100,214,1)'></td>
+ <td width='1' style='background-color: rgba(111,100,218,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,223,1)'></td>
+ <td width='1' style='background-color: rgba(88,100,227,1)'></td>
+ <td width='1' style='background-color: rgba(73,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(53,100,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,100,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,88,53,1)'></td>
+ <td width='1' style='background-color: rgba(235,88,73,1)'></td>
+ <td width='1' style='background-color: rgba(231,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(227,88,100,1)'></td>
+ <td width='1' style='background-color: rgba(223,88,111,1)'></td>
+ <td width='1' style='background-color: rgba(218,88,121,1)'></td>
+ <td width='1' style='background-color: rgba(214,88,130,1)'></td>
+ <td width='1' style='background-color: rgba(209,88,138,1)'></td>
+ <td width='1' style='background-color: rgba(204,88,145,1)'></td>
+ <td width='1' style='background-color: rgba(199,88,152,1)'></td>
+ <td width='1' style='background-color: rgba(194,88,159,1)'></td>
+ <td width='1' style='background-color: rgba(189,88,166,1)'></td>
+ <td width='1' style='background-color: rgba(183,88,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,88,178,1)'></td>
+ <td width='1' style='background-color: rgba(172,88,183,1)'></td>
+ <td width='1' style='background-color: rgba(166,88,189,1)'></td>
+ <td width='1' style='background-color: rgba(159,88,194,1)'></td>
+ <td width='1' style='background-color: rgba(152,88,199,1)'></td>
+ <td width='1' style='background-color: rgba(145,88,204,1)'></td>
+ <td width='1' style='background-color: rgba(138,88,209,1)'></td>
+ <td width='1' style='background-color: rgba(130,88,214,1)'></td>
+ <td width='1' style='background-color: rgba(121,88,218,1)'></td>
+ <td width='1' style='background-color: rgba(111,88,223,1)'></td>
+ <td width='1' style='background-color: rgba(100,88,227,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,231,1)'></td>
+ <td width='1' style='background-color: rgba(73,88,235,1)'></td>
+ <td width='1' style='background-color: rgba(53,88,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,243,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,73,53,1)'></td>
+ <td width='1' style='background-color: rgba(239,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(235,73,88,1)'></td>
+ <td width='1' style='background-color: rgba(231,73,100,1)'></td>
+ <td width='1' style='background-color: rgba(227,73,111,1)'></td>
+ <td width='1' style='background-color: rgba(223,73,121,1)'></td>
+ <td width='1' style='background-color: rgba(218,73,130,1)'></td>
+ <td width='1' style='background-color: rgba(214,73,138,1)'></td>
+ <td width='1' style='background-color: rgba(209,73,145,1)'></td>
+ <td width='1' style='background-color: rgba(204,73,152,1)'></td>
+ <td width='1' style='background-color: rgba(199,73,159,1)'></td>
+ <td width='1' style='background-color: rgba(194,73,166,1)'></td>
+ <td width='1' style='background-color: rgba(189,73,172,1)'></td>
+ <td width='1' style='background-color: rgba(183,73,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,73,183,1)'></td>
+ <td width='1' style='background-color: rgba(172,73,189,1)'></td>
+ <td width='1' style='background-color: rgba(166,73,194,1)'></td>
+ <td width='1' style='background-color: rgba(159,73,199,1)'></td>
+ <td width='1' style='background-color: rgba(152,73,204,1)'></td>
+ <td width='1' style='background-color: rgba(145,73,209,1)'></td>
+ <td width='1' style='background-color: rgba(138,73,214,1)'></td>
+ <td width='1' style='background-color: rgba(130,73,218,1)'></td>
+ <td width='1' style='background-color: rgba(121,73,223,1)'></td>
+ <td width='1' style='background-color: rgba(111,73,227,1)'></td>
+ <td width='1' style='background-color: rgba(100,73,231,1)'></td>
+ <td width='1' style='background-color: rgba(88,73,235,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,239,1)'></td>
+ <td width='1' style='background-color: rgba(53,73,243,1)'></td>
+ <td width='1' style='background-color: rgba(0,73,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,53,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,53,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(243,53,73,1)'></td>
+ <td width='1' style='background-color: rgba(239,53,88,1)'></td>
+ <td width='1' style='background-color: rgba(235,53,100,1)'></td>
+ <td width='1' style='background-color: rgba(231,53,111,1)'></td>
+ <td width='1' style='background-color: rgba(227,53,121,1)'></td>
+ <td width='1' style='background-color: rgba(223,53,130,1)'></td>
+ <td width='1' style='background-color: rgba(218,53,138,1)'></td>
+ <td width='1' style='background-color: rgba(214,53,145,1)'></td>
+ <td width='1' style='background-color: rgba(209,53,152,1)'></td>
+ <td width='1' style='background-color: rgba(204,53,159,1)'></td>
+ <td width='1' style='background-color: rgba(199,53,166,1)'></td>
+ <td width='1' style='background-color: rgba(194,53,172,1)'></td>
+ <td width='1' style='background-color: rgba(189,53,178,1)'></td>
+ <td width='1' style='background-color: rgba(183,53,183,1)'></td>
+ <td width='1' style='background-color: rgba(178,53,189,1)'></td>
+ <td width='1' style='background-color: rgba(172,53,194,1)'></td>
+ <td width='1' style='background-color: rgba(166,53,199,1)'></td>
+ <td width='1' style='background-color: rgba(159,53,204,1)'></td>
+ <td width='1' style='background-color: rgba(152,53,209,1)'></td>
+ <td width='1' style='background-color: rgba(145,53,214,1)'></td>
+ <td width='1' style='background-color: rgba(138,53,218,1)'></td>
+ <td width='1' style='background-color: rgba(130,53,223,1)'></td>
+ <td width='1' style='background-color: rgba(121,53,227,1)'></td>
+ <td width='1' style='background-color: rgba(111,53,231,1)'></td>
+ <td width='1' style='background-color: rgba(100,53,235,1)'></td>
+ <td width='1' style='background-color: rgba(88,53,239,1)'></td>
+ <td width='1' style='background-color: rgba(73,53,243,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,251,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,53,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,73,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,88,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,100,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,111,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,121,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,130,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,138,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,145,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,152,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,159,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,166,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,172,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,178,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,189,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,194,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,199,1)'></td>
+ <td width='1' style='background-color: rgba(166,0,204,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,209,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,214,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,218,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,223,1)'></td>
+ <td width='1' style='background-color: rgba(130,0,227,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,231,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,235,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,239,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,243,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,251,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-i/basi2c16.png b/image/test/reftest/pngsuite-basic-i/basi2c16.png
new file mode 100644
index 0000000000..cd7e50f914
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi2c16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi3p01.html b/image/test/reftest/pngsuite-basic-i/basi3p01.html
new file mode 100644
index 0000000000..2cb512200a
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi3p01.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-i/basi3p01.png b/image/test/reftest/pngsuite-basic-i/basi3p01.png
new file mode 100644
index 0000000000..00a7cea6c2
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi3p01.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi3p02.html b/image/test/reftest/pngsuite-basic-i/basi3p02.html
new file mode 100644
index 0000000000..4555fbb9b9
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi3p02.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-i/basi3p02.png b/image/test/reftest/pngsuite-basic-i/basi3p02.png
new file mode 100644
index 0000000000..bb16b44b30
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi3p02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi3p04.html b/image/test/reftest/pngsuite-basic-i/basi3p04.html
new file mode 100644
index 0000000000..dc2a121de2
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi3p04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-i/basi3p04.png b/image/test/reftest/pngsuite-basic-i/basi3p04.png
new file mode 100644
index 0000000000..b4e888e247
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi3p08.html b/image/test/reftest/pngsuite-basic-i/basi3p08.html
new file mode 100644
index 0000000000..78b72c61c6
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi3p08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(21,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,28,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,28,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,28,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,28,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,21,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(59,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(59,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(59,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(59,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,74,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(123,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,123,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,140,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,112,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,112,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,112,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,112,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(168,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,122,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,122,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,122,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,122,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(122,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(122,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(122,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(122,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,168,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(192,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,192,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(202,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,153,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,153,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,153,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,153,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(221,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,160,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,160,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,160,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,160,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(160,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(160,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(160,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(160,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(230,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,238,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-i/basi3p08.png b/image/test/reftest/pngsuite-basic-i/basi3p08.png
new file mode 100644
index 0000000000..50a6d1cac7
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi3p08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi4a08.png b/image/test/reftest/pngsuite-basic-i/basi4a08.png
new file mode 100644
index 0000000000..398132be5f
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi4a08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi4a16.png b/image/test/reftest/pngsuite-basic-i/basi4a16.png
new file mode 100644
index 0000000000..51192e7311
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi4a16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi6a08.png b/image/test/reftest/pngsuite-basic-i/basi6a08.png
new file mode 100644
index 0000000000..aecb32e0d9
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi6a08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/basi6a16.png b/image/test/reftest/pngsuite-basic-i/basi6a16.png
new file mode 100644
index 0000000000..4181533ad8
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/basi6a16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-i/reftest.list b/image/test/reftest/pngsuite-basic-i/reftest.list
new file mode 100644
index 0000000000..bc61af89d8
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-i/reftest.list
@@ -0,0 +1,33 @@
+# PngSuite - Basic formats (interlaced)
+
+
+# basi0g01 - black & white
+== basi0g01.png basi0g01.html
+# basi0g02 - 2 bit (4 level) grayscale
+== basi0g02.png basi0g02.html
+# basi0g04 - 4 bit (16 level) grayscale
+== basi0g04.png basi0g04.html
+# basi0g08 - 8 bit (256 level) grayscale
+== basi0g08.png basi0g08.html
+# basi0g16 - 16 bit (64k level) grayscale
+== basi0g16.png basi0g16.html
+# basi2c08 - 3x8 bits rgb color
+== basi2c08.png basi2c08.html
+# basi2c16 - 3x16 bits rgb color
+== basi2c16.png basi2c16.html
+# basi3p01 - 1 bit (2 color) paletted
+== basi3p01.png basi3p01.html
+# basi3p02 - 2 bit (4 color) paletted
+== basi3p02.png basi3p02.html
+# basi3p04 - 4 bit (16 color) paletted
+== basi3p04.png basi3p04.html
+# basi3p08 - 8 bit (256 color) paletted
+== basi3p08.png basi3p08.html
+# basi4a08 - 8 bit grayscale + 8 bit alpha-channel
+#== basi4a08.png basi4a08.html
+# basi4a16 - 16 bit grayscale + 16 bit alpha-channel
+#== basi4a16.png basi4a16.html
+# basi6a08 - 3x8 bits rgb color + 8 bit alpha-channel
+#== basi6a08.png basi6a08.html
+# basi6a16 - 3x16 bits rgb color + 16 bit alpha-channel
+#== basi6a16.png basi6a16.html
diff --git a/image/test/reftest/pngsuite-basic-n/basn0g01.html b/image/test/reftest/pngsuite-basic-n/basn0g01.html
new file mode 100644
index 0000000000..7389a1b66e
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn0g01.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-n/basn0g01.png b/image/test/reftest/pngsuite-basic-n/basn0g01.png
new file mode 100644
index 0000000000..1d722423aa
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn0g01.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn0g02.html b/image/test/reftest/pngsuite-basic-n/basn0g02.html
new file mode 100644
index 0000000000..538afad142
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn0g02.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-n/basn0g02.png b/image/test/reftest/pngsuite-basic-n/basn0g02.png
new file mode 100644
index 0000000000..508332418f
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn0g02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn0g04.html b/image/test/reftest/pngsuite-basic-n/basn0g04.html
new file mode 100644
index 0000000000..d782230d4b
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn0g04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-n/basn0g04.png b/image/test/reftest/pngsuite-basic-n/basn0g04.png
new file mode 100644
index 0000000000..0bf3687863
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn0g04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn0g08.html b/image/test/reftest/pngsuite-basic-n/basn0g08.html
new file mode 100644
index 0000000000..5aaf11cabb
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn0g08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-n/basn0g08.png b/image/test/reftest/pngsuite-basic-n/basn0g08.png
new file mode 100644
index 0000000000..23c82379a2
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn0g08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn0g16.html b/image/test/reftest/pngsuite-basic-n/basn0g16.html
new file mode 100644
index 0000000000..fc18c727be
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn0g16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(104,104,104,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(83,83,83,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,100,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(108,108,108,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(104,104,104,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(83,83,83,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,100,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(108,108,108,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(104,104,104,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(97,97,97,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(65,65,65,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(49,49,49,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-n/basn0g16.png b/image/test/reftest/pngsuite-basic-n/basn0g16.png
new file mode 100644
index 0000000000..e7c82f78eb
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn0g16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn2c08.html b/image/test/reftest/pngsuite-basic-n/basn2c08.html
new file mode 100644
index 0000000000..e30216bdf0
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,253,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,253,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,252,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,252,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,249,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,249,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,249,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,248,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,246,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,245,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,245,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,244,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,244,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,243,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,243,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,242,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,241,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,241,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,240,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,237,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,237,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,236,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,236,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,235,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,235,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,234,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,233,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,233,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,232,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,232,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,226,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,226,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,225,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,225,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,222,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,220,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,220,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,219,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,218,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,218,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,217,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,217,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,216,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,214,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,214,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,213,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,213,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,211,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,210,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,210,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,209,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,209,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,208,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,205,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,205,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,204,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,203,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,203,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,201,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,200,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,200,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,197,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,197,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,196,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,195,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,195,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,194,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,194,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,193,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,190,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,190,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,189,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,188,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,188,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,185,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,184,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,184,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,182,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,182,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,181,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,179,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,178,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,178,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,177,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,176,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,173,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,172,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,171,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,170,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,170,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,169,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,165,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,164,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,163,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,162,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,161,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,160,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,160,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,157,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,156,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,156,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,154,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,153,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,152,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,149,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,148,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,147,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,146,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,145,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,144,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,141,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,139,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,138,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,137,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,136,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,133,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,132,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,130,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,129,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,128,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,122,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,120,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,116,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,114,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,112,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,107,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,106,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,99,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,96,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,92,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,90,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,89,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,84,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,82,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,80,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,76,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,72,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,70,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,68,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,66,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,64,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,59,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,56,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,50,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,43,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,34,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,28,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,253,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,253,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,252,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,252,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,249,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,249,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,249,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,248,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,248,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,244,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,244,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,240,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,237,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,237,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,225,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,225,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,220,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,220,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,216,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,215,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,215,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,210,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,210,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,207,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,207,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,206,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,206,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,201,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,200,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,200,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,196,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,195,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,195,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,191,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,190,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,190,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,187,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,186,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,185,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,184,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,184,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,181,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,179,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,176,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,175,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,175,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,173,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,170,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,170,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,169,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,167,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,167,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,161,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,160,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,160,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,158,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,157,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,153,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,150,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,149,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,148,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,147,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,143,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,142,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,141,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,135,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,134,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,133,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,132,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,130,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,128,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,127,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,126,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,125,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,124,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,122,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,119,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,118,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,117,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,116,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,114,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,112,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,110,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,109,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,107,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,106,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,103,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,99,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,98,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,96,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,95,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,93,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,92,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,90,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,89,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,85,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,84,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,82,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,80,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,78,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,76,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,72,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,70,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,68,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,66,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,64,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,61,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,59,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,56,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,50,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,46,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,43,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,39,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,34,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,28,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(253,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(253,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(252,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(252,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(249,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(249,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(249,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(248,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(248,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(245,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(245,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(244,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(244,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(241,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(241,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(237,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(237,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(233,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(233,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(229,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(229,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(225,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(225,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(224,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(223,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(223,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(220,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(220,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(219,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(217,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(217,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(216,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(215,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(215,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(211,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(210,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(210,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(207,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(207,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(206,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(201,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(200,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(200,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(196,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(195,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(195,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(191,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(187,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(186,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(186,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(185,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(184,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(184,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(182,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(182,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(179,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(176,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(175,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(175,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(174,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(170,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(170,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(167,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(167,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(163,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(162,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(161,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(160,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(160,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(158,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(157,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(154,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(153,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(151,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(151,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(150,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(149,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(148,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(146,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(143,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(142,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(141,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(139,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(135,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(134,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(133,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(131,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(130,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(128,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(127,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(126,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(124,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(122,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(119,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(118,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(117,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(116,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(115,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(114,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(112,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(110,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(107,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(106,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(105,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(103,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(98,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(95,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(93,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(89,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(85,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(80,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(78,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(72,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(70,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(66,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(64,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(61,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(56,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(46,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(39,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(28,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-n/basn2c08.png b/image/test/reftest/pngsuite-basic-n/basn2c08.png
new file mode 100644
index 0000000000..db5ad15865
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn2c16.html b/image/test/reftest/pngsuite-basic-n/basn2c16.html
new file mode 100644
index 0000000000..dd08f0e3d0
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn2c16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,251,53,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,247,53,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,73,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,243,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,243,73,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,88,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,239,53,1)'></td>
+ <td width='1' style='background-color: rgba(73,239,73,1)'></td>
+ <td width='1' style='background-color: rgba(53,239,88,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,100,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,235,53,1)'></td>
+ <td width='1' style='background-color: rgba(88,235,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,235,88,1)'></td>
+ <td width='1' style='background-color: rgba(53,235,100,1)'></td>
+ <td width='1' style='background-color: rgba(0,235,111,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,231,53,1)'></td>
+ <td width='1' style='background-color: rgba(100,231,73,1)'></td>
+ <td width='1' style='background-color: rgba(88,231,88,1)'></td>
+ <td width='1' style='background-color: rgba(73,231,100,1)'></td>
+ <td width='1' style='background-color: rgba(53,231,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,231,121,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,227,53,1)'></td>
+ <td width='1' style='background-color: rgba(111,227,73,1)'></td>
+ <td width='1' style='background-color: rgba(100,227,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,227,100,1)'></td>
+ <td width='1' style='background-color: rgba(73,227,111,1)'></td>
+ <td width='1' style='background-color: rgba(53,227,121,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,130,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,223,53,1)'></td>
+ <td width='1' style='background-color: rgba(121,223,73,1)'></td>
+ <td width='1' style='background-color: rgba(111,223,88,1)'></td>
+ <td width='1' style='background-color: rgba(100,223,100,1)'></td>
+ <td width='1' style='background-color: rgba(88,223,111,1)'></td>
+ <td width='1' style='background-color: rgba(73,223,121,1)'></td>
+ <td width='1' style='background-color: rgba(53,223,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,223,138,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,218,53,1)'></td>
+ <td width='1' style='background-color: rgba(130,218,73,1)'></td>
+ <td width='1' style='background-color: rgba(121,218,88,1)'></td>
+ <td width='1' style='background-color: rgba(111,218,100,1)'></td>
+ <td width='1' style='background-color: rgba(100,218,111,1)'></td>
+ <td width='1' style='background-color: rgba(88,218,121,1)'></td>
+ <td width='1' style='background-color: rgba(73,218,130,1)'></td>
+ <td width='1' style='background-color: rgba(53,218,138,1)'></td>
+ <td width='1' style='background-color: rgba(0,218,145,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,214,53,1)'></td>
+ <td width='1' style='background-color: rgba(138,214,73,1)'></td>
+ <td width='1' style='background-color: rgba(130,214,88,1)'></td>
+ <td width='1' style='background-color: rgba(121,214,100,1)'></td>
+ <td width='1' style='background-color: rgba(111,214,111,1)'></td>
+ <td width='1' style='background-color: rgba(100,214,121,1)'></td>
+ <td width='1' style='background-color: rgba(88,214,130,1)'></td>
+ <td width='1' style='background-color: rgba(73,214,138,1)'></td>
+ <td width='1' style='background-color: rgba(53,214,145,1)'></td>
+ <td width='1' style='background-color: rgba(0,214,152,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,209,53,1)'></td>
+ <td width='1' style='background-color: rgba(145,209,73,1)'></td>
+ <td width='1' style='background-color: rgba(138,209,88,1)'></td>
+ <td width='1' style='background-color: rgba(130,209,100,1)'></td>
+ <td width='1' style='background-color: rgba(121,209,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,209,121,1)'></td>
+ <td width='1' style='background-color: rgba(100,209,130,1)'></td>
+ <td width='1' style='background-color: rgba(88,209,138,1)'></td>
+ <td width='1' style='background-color: rgba(73,209,145,1)'></td>
+ <td width='1' style='background-color: rgba(53,209,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,159,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,204,53,1)'></td>
+ <td width='1' style='background-color: rgba(152,204,73,1)'></td>
+ <td width='1' style='background-color: rgba(145,204,88,1)'></td>
+ <td width='1' style='background-color: rgba(138,204,100,1)'></td>
+ <td width='1' style='background-color: rgba(130,204,111,1)'></td>
+ <td width='1' style='background-color: rgba(121,204,121,1)'></td>
+ <td width='1' style='background-color: rgba(111,204,130,1)'></td>
+ <td width='1' style='background-color: rgba(100,204,138,1)'></td>
+ <td width='1' style='background-color: rgba(88,204,145,1)'></td>
+ <td width='1' style='background-color: rgba(73,204,152,1)'></td>
+ <td width='1' style='background-color: rgba(53,204,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,204,166,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,199,53,1)'></td>
+ <td width='1' style='background-color: rgba(159,199,73,1)'></td>
+ <td width='1' style='background-color: rgba(152,199,88,1)'></td>
+ <td width='1' style='background-color: rgba(145,199,100,1)'></td>
+ <td width='1' style='background-color: rgba(138,199,111,1)'></td>
+ <td width='1' style='background-color: rgba(130,199,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,199,130,1)'></td>
+ <td width='1' style='background-color: rgba(111,199,138,1)'></td>
+ <td width='1' style='background-color: rgba(100,199,145,1)'></td>
+ <td width='1' style='background-color: rgba(88,199,152,1)'></td>
+ <td width='1' style='background-color: rgba(73,199,159,1)'></td>
+ <td width='1' style='background-color: rgba(53,199,166,1)'></td>
+ <td width='1' style='background-color: rgba(0,199,172,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,194,53,1)'></td>
+ <td width='1' style='background-color: rgba(166,194,73,1)'></td>
+ <td width='1' style='background-color: rgba(159,194,88,1)'></td>
+ <td width='1' style='background-color: rgba(152,194,100,1)'></td>
+ <td width='1' style='background-color: rgba(145,194,111,1)'></td>
+ <td width='1' style='background-color: rgba(138,194,121,1)'></td>
+ <td width='1' style='background-color: rgba(130,194,130,1)'></td>
+ <td width='1' style='background-color: rgba(121,194,138,1)'></td>
+ <td width='1' style='background-color: rgba(111,194,145,1)'></td>
+ <td width='1' style='background-color: rgba(100,194,152,1)'></td>
+ <td width='1' style='background-color: rgba(88,194,159,1)'></td>
+ <td width='1' style='background-color: rgba(73,194,166,1)'></td>
+ <td width='1' style='background-color: rgba(53,194,172,1)'></td>
+ <td width='1' style='background-color: rgba(0,194,178,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,189,53,1)'></td>
+ <td width='1' style='background-color: rgba(172,189,73,1)'></td>
+ <td width='1' style='background-color: rgba(166,189,88,1)'></td>
+ <td width='1' style='background-color: rgba(159,189,100,1)'></td>
+ <td width='1' style='background-color: rgba(152,189,111,1)'></td>
+ <td width='1' style='background-color: rgba(145,189,121,1)'></td>
+ <td width='1' style='background-color: rgba(138,189,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,189,138,1)'></td>
+ <td width='1' style='background-color: rgba(121,189,145,1)'></td>
+ <td width='1' style='background-color: rgba(111,189,152,1)'></td>
+ <td width='1' style='background-color: rgba(100,189,159,1)'></td>
+ <td width='1' style='background-color: rgba(88,189,166,1)'></td>
+ <td width='1' style='background-color: rgba(73,189,172,1)'></td>
+ <td width='1' style='background-color: rgba(53,189,178,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,183,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,53,1)'></td>
+ <td width='1' style='background-color: rgba(178,183,73,1)'></td>
+ <td width='1' style='background-color: rgba(172,183,88,1)'></td>
+ <td width='1' style='background-color: rgba(166,183,100,1)'></td>
+ <td width='1' style='background-color: rgba(159,183,111,1)'></td>
+ <td width='1' style='background-color: rgba(152,183,121,1)'></td>
+ <td width='1' style='background-color: rgba(145,183,130,1)'></td>
+ <td width='1' style='background-color: rgba(138,183,138,1)'></td>
+ <td width='1' style='background-color: rgba(130,183,145,1)'></td>
+ <td width='1' style='background-color: rgba(121,183,152,1)'></td>
+ <td width='1' style='background-color: rgba(111,183,159,1)'></td>
+ <td width='1' style='background-color: rgba(100,183,166,1)'></td>
+ <td width='1' style='background-color: rgba(88,183,172,1)'></td>
+ <td width='1' style='background-color: rgba(73,183,178,1)'></td>
+ <td width='1' style='background-color: rgba(53,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,183,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,178,53,1)'></td>
+ <td width='1' style='background-color: rgba(183,178,73,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,88,1)'></td>
+ <td width='1' style='background-color: rgba(172,178,100,1)'></td>
+ <td width='1' style='background-color: rgba(166,178,111,1)'></td>
+ <td width='1' style='background-color: rgba(159,178,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,178,130,1)'></td>
+ <td width='1' style='background-color: rgba(145,178,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,178,145,1)'></td>
+ <td width='1' style='background-color: rgba(130,178,152,1)'></td>
+ <td width='1' style='background-color: rgba(121,178,159,1)'></td>
+ <td width='1' style='background-color: rgba(111,178,166,1)'></td>
+ <td width='1' style='background-color: rgba(100,178,172,1)'></td>
+ <td width='1' style='background-color: rgba(88,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(73,178,183,1)'></td>
+ <td width='1' style='background-color: rgba(53,178,189,1)'></td>
+ <td width='1' style='background-color: rgba(0,178,194,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,172,53,1)'></td>
+ <td width='1' style='background-color: rgba(189,172,73,1)'></td>
+ <td width='1' style='background-color: rgba(183,172,88,1)'></td>
+ <td width='1' style='background-color: rgba(178,172,100,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,111,1)'></td>
+ <td width='1' style='background-color: rgba(166,172,121,1)'></td>
+ <td width='1' style='background-color: rgba(159,172,130,1)'></td>
+ <td width='1' style='background-color: rgba(152,172,138,1)'></td>
+ <td width='1' style='background-color: rgba(145,172,145,1)'></td>
+ <td width='1' style='background-color: rgba(138,172,152,1)'></td>
+ <td width='1' style='background-color: rgba(130,172,159,1)'></td>
+ <td width='1' style='background-color: rgba(121,172,166,1)'></td>
+ <td width='1' style='background-color: rgba(111,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(100,172,178,1)'></td>
+ <td width='1' style='background-color: rgba(88,172,183,1)'></td>
+ <td width='1' style='background-color: rgba(73,172,189,1)'></td>
+ <td width='1' style='background-color: rgba(53,172,194,1)'></td>
+ <td width='1' style='background-color: rgba(0,172,199,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,166,53,1)'></td>
+ <td width='1' style='background-color: rgba(194,166,73,1)'></td>
+ <td width='1' style='background-color: rgba(189,166,88,1)'></td>
+ <td width='1' style='background-color: rgba(183,166,100,1)'></td>
+ <td width='1' style='background-color: rgba(178,166,111,1)'></td>
+ <td width='1' style='background-color: rgba(172,166,121,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,130,1)'></td>
+ <td width='1' style='background-color: rgba(159,166,138,1)'></td>
+ <td width='1' style='background-color: rgba(152,166,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,166,152,1)'></td>
+ <td width='1' style='background-color: rgba(138,166,159,1)'></td>
+ <td width='1' style='background-color: rgba(130,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(121,166,172,1)'></td>
+ <td width='1' style='background-color: rgba(111,166,178,1)'></td>
+ <td width='1' style='background-color: rgba(100,166,183,1)'></td>
+ <td width='1' style='background-color: rgba(88,166,189,1)'></td>
+ <td width='1' style='background-color: rgba(73,166,194,1)'></td>
+ <td width='1' style='background-color: rgba(53,166,199,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,204,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,159,53,1)'></td>
+ <td width='1' style='background-color: rgba(199,159,73,1)'></td>
+ <td width='1' style='background-color: rgba(194,159,88,1)'></td>
+ <td width='1' style='background-color: rgba(189,159,100,1)'></td>
+ <td width='1' style='background-color: rgba(183,159,111,1)'></td>
+ <td width='1' style='background-color: rgba(178,159,121,1)'></td>
+ <td width='1' style='background-color: rgba(172,159,130,1)'></td>
+ <td width='1' style='background-color: rgba(166,159,138,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,145,1)'></td>
+ <td width='1' style='background-color: rgba(152,159,152,1)'></td>
+ <td width='1' style='background-color: rgba(145,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(138,159,166,1)'></td>
+ <td width='1' style='background-color: rgba(130,159,172,1)'></td>
+ <td width='1' style='background-color: rgba(121,159,178,1)'></td>
+ <td width='1' style='background-color: rgba(111,159,183,1)'></td>
+ <td width='1' style='background-color: rgba(100,159,189,1)'></td>
+ <td width='1' style='background-color: rgba(88,159,194,1)'></td>
+ <td width='1' style='background-color: rgba(73,159,199,1)'></td>
+ <td width='1' style='background-color: rgba(53,159,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,159,209,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,152,53,1)'></td>
+ <td width='1' style='background-color: rgba(204,152,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,152,88,1)'></td>
+ <td width='1' style='background-color: rgba(194,152,100,1)'></td>
+ <td width='1' style='background-color: rgba(189,152,111,1)'></td>
+ <td width='1' style='background-color: rgba(183,152,121,1)'></td>
+ <td width='1' style='background-color: rgba(178,152,130,1)'></td>
+ <td width='1' style='background-color: rgba(172,152,138,1)'></td>
+ <td width='1' style='background-color: rgba(166,152,145,1)'></td>
+ <td width='1' style='background-color: rgba(159,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,159,1)'></td>
+ <td width='1' style='background-color: rgba(145,152,166,1)'></td>
+ <td width='1' style='background-color: rgba(138,152,172,1)'></td>
+ <td width='1' style='background-color: rgba(130,152,178,1)'></td>
+ <td width='1' style='background-color: rgba(121,152,183,1)'></td>
+ <td width='1' style='background-color: rgba(111,152,189,1)'></td>
+ <td width='1' style='background-color: rgba(100,152,194,1)'></td>
+ <td width='1' style='background-color: rgba(88,152,199,1)'></td>
+ <td width='1' style='background-color: rgba(73,152,204,1)'></td>
+ <td width='1' style='background-color: rgba(53,152,209,1)'></td>
+ <td width='1' style='background-color: rgba(0,152,214,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,145,53,1)'></td>
+ <td width='1' style='background-color: rgba(209,145,73,1)'></td>
+ <td width='1' style='background-color: rgba(204,145,88,1)'></td>
+ <td width='1' style='background-color: rgba(199,145,100,1)'></td>
+ <td width='1' style='background-color: rgba(194,145,111,1)'></td>
+ <td width='1' style='background-color: rgba(189,145,121,1)'></td>
+ <td width='1' style='background-color: rgba(183,145,130,1)'></td>
+ <td width='1' style='background-color: rgba(178,145,138,1)'></td>
+ <td width='1' style='background-color: rgba(172,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(166,145,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,145,159,1)'></td>
+ <td width='1' style='background-color: rgba(152,145,166,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,172,1)'></td>
+ <td width='1' style='background-color: rgba(138,145,178,1)'></td>
+ <td width='1' style='background-color: rgba(130,145,183,1)'></td>
+ <td width='1' style='background-color: rgba(121,145,189,1)'></td>
+ <td width='1' style='background-color: rgba(111,145,194,1)'></td>
+ <td width='1' style='background-color: rgba(100,145,199,1)'></td>
+ <td width='1' style='background-color: rgba(88,145,204,1)'></td>
+ <td width='1' style='background-color: rgba(73,145,209,1)'></td>
+ <td width='1' style='background-color: rgba(53,145,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,218,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,138,53,1)'></td>
+ <td width='1' style='background-color: rgba(214,138,73,1)'></td>
+ <td width='1' style='background-color: rgba(209,138,88,1)'></td>
+ <td width='1' style='background-color: rgba(204,138,100,1)'></td>
+ <td width='1' style='background-color: rgba(199,138,111,1)'></td>
+ <td width='1' style='background-color: rgba(194,138,121,1)'></td>
+ <td width='1' style='background-color: rgba(189,138,130,1)'></td>
+ <td width='1' style='background-color: rgba(183,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(178,138,145,1)'></td>
+ <td width='1' style='background-color: rgba(172,138,152,1)'></td>
+ <td width='1' style='background-color: rgba(166,138,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,138,166,1)'></td>
+ <td width='1' style='background-color: rgba(152,138,172,1)'></td>
+ <td width='1' style='background-color: rgba(145,138,178,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,183,1)'></td>
+ <td width='1' style='background-color: rgba(130,138,189,1)'></td>
+ <td width='1' style='background-color: rgba(121,138,194,1)'></td>
+ <td width='1' style='background-color: rgba(111,138,199,1)'></td>
+ <td width='1' style='background-color: rgba(100,138,204,1)'></td>
+ <td width='1' style='background-color: rgba(88,138,209,1)'></td>
+ <td width='1' style='background-color: rgba(73,138,214,1)'></td>
+ <td width='1' style='background-color: rgba(53,138,218,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,130,53,1)'></td>
+ <td width='1' style='background-color: rgba(218,130,73,1)'></td>
+ <td width='1' style='background-color: rgba(214,130,88,1)'></td>
+ <td width='1' style='background-color: rgba(209,130,100,1)'></td>
+ <td width='1' style='background-color: rgba(204,130,111,1)'></td>
+ <td width='1' style='background-color: rgba(199,130,121,1)'></td>
+ <td width='1' style='background-color: rgba(194,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(189,130,138,1)'></td>
+ <td width='1' style='background-color: rgba(183,130,145,1)'></td>
+ <td width='1' style='background-color: rgba(178,130,152,1)'></td>
+ <td width='1' style='background-color: rgba(172,130,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,130,166,1)'></td>
+ <td width='1' style='background-color: rgba(159,130,172,1)'></td>
+ <td width='1' style='background-color: rgba(152,130,178,1)'></td>
+ <td width='1' style='background-color: rgba(145,130,183,1)'></td>
+ <td width='1' style='background-color: rgba(138,130,189,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,194,1)'></td>
+ <td width='1' style='background-color: rgba(121,130,199,1)'></td>
+ <td width='1' style='background-color: rgba(111,130,204,1)'></td>
+ <td width='1' style='background-color: rgba(100,130,209,1)'></td>
+ <td width='1' style='background-color: rgba(88,130,214,1)'></td>
+ <td width='1' style='background-color: rgba(73,130,218,1)'></td>
+ <td width='1' style='background-color: rgba(53,130,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,130,227,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,121,53,1)'></td>
+ <td width='1' style='background-color: rgba(223,121,73,1)'></td>
+ <td width='1' style='background-color: rgba(218,121,88,1)'></td>
+ <td width='1' style='background-color: rgba(214,121,100,1)'></td>
+ <td width='1' style='background-color: rgba(209,121,111,1)'></td>
+ <td width='1' style='background-color: rgba(204,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(199,121,130,1)'></td>
+ <td width='1' style='background-color: rgba(194,121,138,1)'></td>
+ <td width='1' style='background-color: rgba(189,121,145,1)'></td>
+ <td width='1' style='background-color: rgba(183,121,152,1)'></td>
+ <td width='1' style='background-color: rgba(178,121,159,1)'></td>
+ <td width='1' style='background-color: rgba(172,121,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,121,172,1)'></td>
+ <td width='1' style='background-color: rgba(159,121,178,1)'></td>
+ <td width='1' style='background-color: rgba(152,121,183,1)'></td>
+ <td width='1' style='background-color: rgba(145,121,189,1)'></td>
+ <td width='1' style='background-color: rgba(138,121,194,1)'></td>
+ <td width='1' style='background-color: rgba(130,121,199,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,204,1)'></td>
+ <td width='1' style='background-color: rgba(111,121,209,1)'></td>
+ <td width='1' style='background-color: rgba(100,121,214,1)'></td>
+ <td width='1' style='background-color: rgba(88,121,218,1)'></td>
+ <td width='1' style='background-color: rgba(73,121,223,1)'></td>
+ <td width='1' style='background-color: rgba(53,121,227,1)'></td>
+ <td width='1' style='background-color: rgba(0,121,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,111,53,1)'></td>
+ <td width='1' style='background-color: rgba(227,111,73,1)'></td>
+ <td width='1' style='background-color: rgba(223,111,88,1)'></td>
+ <td width='1' style='background-color: rgba(218,111,100,1)'></td>
+ <td width='1' style='background-color: rgba(214,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(209,111,121,1)'></td>
+ <td width='1' style='background-color: rgba(204,111,130,1)'></td>
+ <td width='1' style='background-color: rgba(199,111,138,1)'></td>
+ <td width='1' style='background-color: rgba(194,111,145,1)'></td>
+ <td width='1' style='background-color: rgba(189,111,152,1)'></td>
+ <td width='1' style='background-color: rgba(183,111,159,1)'></td>
+ <td width='1' style='background-color: rgba(178,111,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,111,172,1)'></td>
+ <td width='1' style='background-color: rgba(166,111,178,1)'></td>
+ <td width='1' style='background-color: rgba(159,111,183,1)'></td>
+ <td width='1' style='background-color: rgba(152,111,189,1)'></td>
+ <td width='1' style='background-color: rgba(145,111,194,1)'></td>
+ <td width='1' style='background-color: rgba(138,111,199,1)'></td>
+ <td width='1' style='background-color: rgba(130,111,204,1)'></td>
+ <td width='1' style='background-color: rgba(121,111,209,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,214,1)'></td>
+ <td width='1' style='background-color: rgba(100,111,218,1)'></td>
+ <td width='1' style='background-color: rgba(88,111,223,1)'></td>
+ <td width='1' style='background-color: rgba(73,111,227,1)'></td>
+ <td width='1' style='background-color: rgba(53,111,231,1)'></td>
+ <td width='1' style='background-color: rgba(0,111,235,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,100,53,1)'></td>
+ <td width='1' style='background-color: rgba(231,100,73,1)'></td>
+ <td width='1' style='background-color: rgba(227,100,88,1)'></td>
+ <td width='1' style='background-color: rgba(223,100,100,1)'></td>
+ <td width='1' style='background-color: rgba(218,100,111,1)'></td>
+ <td width='1' style='background-color: rgba(214,100,121,1)'></td>
+ <td width='1' style='background-color: rgba(209,100,130,1)'></td>
+ <td width='1' style='background-color: rgba(204,100,138,1)'></td>
+ <td width='1' style='background-color: rgba(199,100,145,1)'></td>
+ <td width='1' style='background-color: rgba(194,100,152,1)'></td>
+ <td width='1' style='background-color: rgba(189,100,159,1)'></td>
+ <td width='1' style='background-color: rgba(183,100,166,1)'></td>
+ <td width='1' style='background-color: rgba(178,100,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,100,178,1)'></td>
+ <td width='1' style='background-color: rgba(166,100,183,1)'></td>
+ <td width='1' style='background-color: rgba(159,100,189,1)'></td>
+ <td width='1' style='background-color: rgba(152,100,194,1)'></td>
+ <td width='1' style='background-color: rgba(145,100,199,1)'></td>
+ <td width='1' style='background-color: rgba(138,100,204,1)'></td>
+ <td width='1' style='background-color: rgba(130,100,209,1)'></td>
+ <td width='1' style='background-color: rgba(121,100,214,1)'></td>
+ <td width='1' style='background-color: rgba(111,100,218,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,223,1)'></td>
+ <td width='1' style='background-color: rgba(88,100,227,1)'></td>
+ <td width='1' style='background-color: rgba(73,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(53,100,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,100,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,88,53,1)'></td>
+ <td width='1' style='background-color: rgba(235,88,73,1)'></td>
+ <td width='1' style='background-color: rgba(231,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(227,88,100,1)'></td>
+ <td width='1' style='background-color: rgba(223,88,111,1)'></td>
+ <td width='1' style='background-color: rgba(218,88,121,1)'></td>
+ <td width='1' style='background-color: rgba(214,88,130,1)'></td>
+ <td width='1' style='background-color: rgba(209,88,138,1)'></td>
+ <td width='1' style='background-color: rgba(204,88,145,1)'></td>
+ <td width='1' style='background-color: rgba(199,88,152,1)'></td>
+ <td width='1' style='background-color: rgba(194,88,159,1)'></td>
+ <td width='1' style='background-color: rgba(189,88,166,1)'></td>
+ <td width='1' style='background-color: rgba(183,88,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,88,178,1)'></td>
+ <td width='1' style='background-color: rgba(172,88,183,1)'></td>
+ <td width='1' style='background-color: rgba(166,88,189,1)'></td>
+ <td width='1' style='background-color: rgba(159,88,194,1)'></td>
+ <td width='1' style='background-color: rgba(152,88,199,1)'></td>
+ <td width='1' style='background-color: rgba(145,88,204,1)'></td>
+ <td width='1' style='background-color: rgba(138,88,209,1)'></td>
+ <td width='1' style='background-color: rgba(130,88,214,1)'></td>
+ <td width='1' style='background-color: rgba(121,88,218,1)'></td>
+ <td width='1' style='background-color: rgba(111,88,223,1)'></td>
+ <td width='1' style='background-color: rgba(100,88,227,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,231,1)'></td>
+ <td width='1' style='background-color: rgba(73,88,235,1)'></td>
+ <td width='1' style='background-color: rgba(53,88,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,243,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,73,53,1)'></td>
+ <td width='1' style='background-color: rgba(239,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(235,73,88,1)'></td>
+ <td width='1' style='background-color: rgba(231,73,100,1)'></td>
+ <td width='1' style='background-color: rgba(227,73,111,1)'></td>
+ <td width='1' style='background-color: rgba(223,73,121,1)'></td>
+ <td width='1' style='background-color: rgba(218,73,130,1)'></td>
+ <td width='1' style='background-color: rgba(214,73,138,1)'></td>
+ <td width='1' style='background-color: rgba(209,73,145,1)'></td>
+ <td width='1' style='background-color: rgba(204,73,152,1)'></td>
+ <td width='1' style='background-color: rgba(199,73,159,1)'></td>
+ <td width='1' style='background-color: rgba(194,73,166,1)'></td>
+ <td width='1' style='background-color: rgba(189,73,172,1)'></td>
+ <td width='1' style='background-color: rgba(183,73,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,73,183,1)'></td>
+ <td width='1' style='background-color: rgba(172,73,189,1)'></td>
+ <td width='1' style='background-color: rgba(166,73,194,1)'></td>
+ <td width='1' style='background-color: rgba(159,73,199,1)'></td>
+ <td width='1' style='background-color: rgba(152,73,204,1)'></td>
+ <td width='1' style='background-color: rgba(145,73,209,1)'></td>
+ <td width='1' style='background-color: rgba(138,73,214,1)'></td>
+ <td width='1' style='background-color: rgba(130,73,218,1)'></td>
+ <td width='1' style='background-color: rgba(121,73,223,1)'></td>
+ <td width='1' style='background-color: rgba(111,73,227,1)'></td>
+ <td width='1' style='background-color: rgba(100,73,231,1)'></td>
+ <td width='1' style='background-color: rgba(88,73,235,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,239,1)'></td>
+ <td width='1' style='background-color: rgba(53,73,243,1)'></td>
+ <td width='1' style='background-color: rgba(0,73,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,53,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,53,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(243,53,73,1)'></td>
+ <td width='1' style='background-color: rgba(239,53,88,1)'></td>
+ <td width='1' style='background-color: rgba(235,53,100,1)'></td>
+ <td width='1' style='background-color: rgba(231,53,111,1)'></td>
+ <td width='1' style='background-color: rgba(227,53,121,1)'></td>
+ <td width='1' style='background-color: rgba(223,53,130,1)'></td>
+ <td width='1' style='background-color: rgba(218,53,138,1)'></td>
+ <td width='1' style='background-color: rgba(214,53,145,1)'></td>
+ <td width='1' style='background-color: rgba(209,53,152,1)'></td>
+ <td width='1' style='background-color: rgba(204,53,159,1)'></td>
+ <td width='1' style='background-color: rgba(199,53,166,1)'></td>
+ <td width='1' style='background-color: rgba(194,53,172,1)'></td>
+ <td width='1' style='background-color: rgba(189,53,178,1)'></td>
+ <td width='1' style='background-color: rgba(183,53,183,1)'></td>
+ <td width='1' style='background-color: rgba(178,53,189,1)'></td>
+ <td width='1' style='background-color: rgba(172,53,194,1)'></td>
+ <td width='1' style='background-color: rgba(166,53,199,1)'></td>
+ <td width='1' style='background-color: rgba(159,53,204,1)'></td>
+ <td width='1' style='background-color: rgba(152,53,209,1)'></td>
+ <td width='1' style='background-color: rgba(145,53,214,1)'></td>
+ <td width='1' style='background-color: rgba(138,53,218,1)'></td>
+ <td width='1' style='background-color: rgba(130,53,223,1)'></td>
+ <td width='1' style='background-color: rgba(121,53,227,1)'></td>
+ <td width='1' style='background-color: rgba(111,53,231,1)'></td>
+ <td width='1' style='background-color: rgba(100,53,235,1)'></td>
+ <td width='1' style='background-color: rgba(88,53,239,1)'></td>
+ <td width='1' style='background-color: rgba(73,53,243,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,251,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,53,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,73,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,88,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,100,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,111,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,121,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,130,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,138,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,145,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,152,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,159,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,166,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,172,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,178,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,189,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,194,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,199,1)'></td>
+ <td width='1' style='background-color: rgba(166,0,204,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,209,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,214,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,218,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,223,1)'></td>
+ <td width='1' style='background-color: rgba(130,0,227,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,231,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,235,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,239,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,243,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,251,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-n/basn2c16.png b/image/test/reftest/pngsuite-basic-n/basn2c16.png
new file mode 100644
index 0000000000..50c1cb91a0
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn2c16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn3p01.html b/image/test/reftest/pngsuite-basic-n/basn3p01.html
new file mode 100644
index 0000000000..2cb512200a
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn3p01.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,102,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-n/basn3p01.png b/image/test/reftest/pngsuite-basic-n/basn3p01.png
new file mode 100644
index 0000000000..b145c2b8ef
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn3p01.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn3p02.html b/image/test/reftest/pngsuite-basic-n/basn3p02.html
new file mode 100644
index 0000000000..4555fbb9b9
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn3p02.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-n/basn3p02.png b/image/test/reftest/pngsuite-basic-n/basn3p02.png
new file mode 100644
index 0000000000..8985b3d818
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn3p02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn3p04.html b/image/test/reftest/pngsuite-basic-n/basn3p04.html
new file mode 100644
index 0000000000..dc2a121de2
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn3p04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,221,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-n/basn3p04.png b/image/test/reftest/pngsuite-basic-n/basn3p04.png
new file mode 100644
index 0000000000..0fbf9e827b
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn3p08.html b/image/test/reftest/pngsuite-basic-n/basn3p08.html
new file mode 100644
index 0000000000..78b72c61c6
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn3p08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(21,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,28,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,28,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,28,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,28,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,0,21,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(59,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(59,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(59,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(59,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,74,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,0,102,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(123,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,123,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,102,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(102,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,140,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,112,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,112,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,112,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,112,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,0,155,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(168,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,122,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,122,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,122,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,122,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(122,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(122,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(122,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(122,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,0,168,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(192,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,0,192,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(202,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,0,202,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,153,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,153,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,153,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,153,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,0,212,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(221,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,160,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,160,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,160,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,160,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(160,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(160,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(160,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(160,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,0,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(230,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,238,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,21,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,194,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,102,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(203,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,140,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(213,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,192,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,250,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(250,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,254,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-basic-n/basn3p08.png b/image/test/reftest/pngsuite-basic-n/basn3p08.png
new file mode 100644
index 0000000000..0ddad07e5f
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn3p08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn4a08.png b/image/test/reftest/pngsuite-basic-n/basn4a08.png
new file mode 100644
index 0000000000..3e13052201
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn4a08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn4a16.png b/image/test/reftest/pngsuite-basic-n/basn4a16.png
new file mode 100644
index 0000000000..8243644d07
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn4a16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn6a08.png b/image/test/reftest/pngsuite-basic-n/basn6a08.png
new file mode 100644
index 0000000000..e608738763
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn6a08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/basn6a16.png b/image/test/reftest/pngsuite-basic-n/basn6a16.png
new file mode 100644
index 0000000000..984a99525f
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/basn6a16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-basic-n/reftest.list b/image/test/reftest/pngsuite-basic-n/reftest.list
new file mode 100644
index 0000000000..c59a5a7e47
--- /dev/null
+++ b/image/test/reftest/pngsuite-basic-n/reftest.list
@@ -0,0 +1,33 @@
+# PngSuite - Basic formats (non-interlaced)
+
+
+# basn0g01 - black & white
+== basn0g01.png basn0g01.html
+# basn0g02 - 2 bit (4 level) grayscale
+== basn0g02.png basn0g02.html
+# basn0g04 - 4 bit (16 level) grayscale
+== basn0g04.png basn0g04.html
+# basn0g08 - 8 bit (256 level) grayscale
+== basn0g08.png basn0g08.html
+# basn0g16 - 16 bit (64k level) grayscale
+== basn0g16.png basn0g16.html
+# basn2c08 - 3x8 bits rgb color
+== basn2c08.png basn2c08.html
+# basn2c16 - 3x16 bits rgb color
+== basn2c16.png basn2c16.html
+# basn3p01 - 1 bit (2 color) paletted
+== basn3p01.png basn3p01.html
+# basn3p02 - 2 bit (4 color) paletted
+== basn3p02.png basn3p02.html
+# basn3p04 - 4 bit (16 color) paletted
+== basn3p04.png basn3p04.html
+# basn3p08 - 8 bit (256 color) paletted
+== basn3p08.png basn3p08.html
+# basn4a08 - 8 bit grayscale + 8 bit alpha-channel
+#== basn4a08.png basn4a08.html
+# basn4a16 - 16 bit grayscale + 16 bit alpha-channel
+#== basn4a16.png basn4a16.html
+# basn6a08 - 3x8 bits rgb color + 8 bit alpha-channel
+#== basn6a08.png basn6a08.html
+# basn6a16 - 3x16 bits rgb color + 16 bit alpha-channel
+#== basn6a16.png basn6a16.html
diff --git a/image/test/reftest/pngsuite-chunkorder/color.html b/image/test/reftest/pngsuite-chunkorder/color.html
new file mode 100644
index 0000000000..dd08f0e3d0
--- /dev/null
+++ b/image/test/reftest/pngsuite-chunkorder/color.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,251,53,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,247,53,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,73,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,243,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,243,73,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,88,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,239,53,1)'></td>
+ <td width='1' style='background-color: rgba(73,239,73,1)'></td>
+ <td width='1' style='background-color: rgba(53,239,88,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,100,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,235,53,1)'></td>
+ <td width='1' style='background-color: rgba(88,235,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,235,88,1)'></td>
+ <td width='1' style='background-color: rgba(53,235,100,1)'></td>
+ <td width='1' style='background-color: rgba(0,235,111,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,231,53,1)'></td>
+ <td width='1' style='background-color: rgba(100,231,73,1)'></td>
+ <td width='1' style='background-color: rgba(88,231,88,1)'></td>
+ <td width='1' style='background-color: rgba(73,231,100,1)'></td>
+ <td width='1' style='background-color: rgba(53,231,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,231,121,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,227,53,1)'></td>
+ <td width='1' style='background-color: rgba(111,227,73,1)'></td>
+ <td width='1' style='background-color: rgba(100,227,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,227,100,1)'></td>
+ <td width='1' style='background-color: rgba(73,227,111,1)'></td>
+ <td width='1' style='background-color: rgba(53,227,121,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,130,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,223,53,1)'></td>
+ <td width='1' style='background-color: rgba(121,223,73,1)'></td>
+ <td width='1' style='background-color: rgba(111,223,88,1)'></td>
+ <td width='1' style='background-color: rgba(100,223,100,1)'></td>
+ <td width='1' style='background-color: rgba(88,223,111,1)'></td>
+ <td width='1' style='background-color: rgba(73,223,121,1)'></td>
+ <td width='1' style='background-color: rgba(53,223,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,223,138,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,218,53,1)'></td>
+ <td width='1' style='background-color: rgba(130,218,73,1)'></td>
+ <td width='1' style='background-color: rgba(121,218,88,1)'></td>
+ <td width='1' style='background-color: rgba(111,218,100,1)'></td>
+ <td width='1' style='background-color: rgba(100,218,111,1)'></td>
+ <td width='1' style='background-color: rgba(88,218,121,1)'></td>
+ <td width='1' style='background-color: rgba(73,218,130,1)'></td>
+ <td width='1' style='background-color: rgba(53,218,138,1)'></td>
+ <td width='1' style='background-color: rgba(0,218,145,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,214,53,1)'></td>
+ <td width='1' style='background-color: rgba(138,214,73,1)'></td>
+ <td width='1' style='background-color: rgba(130,214,88,1)'></td>
+ <td width='1' style='background-color: rgba(121,214,100,1)'></td>
+ <td width='1' style='background-color: rgba(111,214,111,1)'></td>
+ <td width='1' style='background-color: rgba(100,214,121,1)'></td>
+ <td width='1' style='background-color: rgba(88,214,130,1)'></td>
+ <td width='1' style='background-color: rgba(73,214,138,1)'></td>
+ <td width='1' style='background-color: rgba(53,214,145,1)'></td>
+ <td width='1' style='background-color: rgba(0,214,152,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,209,53,1)'></td>
+ <td width='1' style='background-color: rgba(145,209,73,1)'></td>
+ <td width='1' style='background-color: rgba(138,209,88,1)'></td>
+ <td width='1' style='background-color: rgba(130,209,100,1)'></td>
+ <td width='1' style='background-color: rgba(121,209,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,209,121,1)'></td>
+ <td width='1' style='background-color: rgba(100,209,130,1)'></td>
+ <td width='1' style='background-color: rgba(88,209,138,1)'></td>
+ <td width='1' style='background-color: rgba(73,209,145,1)'></td>
+ <td width='1' style='background-color: rgba(53,209,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,159,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,204,53,1)'></td>
+ <td width='1' style='background-color: rgba(152,204,73,1)'></td>
+ <td width='1' style='background-color: rgba(145,204,88,1)'></td>
+ <td width='1' style='background-color: rgba(138,204,100,1)'></td>
+ <td width='1' style='background-color: rgba(130,204,111,1)'></td>
+ <td width='1' style='background-color: rgba(121,204,121,1)'></td>
+ <td width='1' style='background-color: rgba(111,204,130,1)'></td>
+ <td width='1' style='background-color: rgba(100,204,138,1)'></td>
+ <td width='1' style='background-color: rgba(88,204,145,1)'></td>
+ <td width='1' style='background-color: rgba(73,204,152,1)'></td>
+ <td width='1' style='background-color: rgba(53,204,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,204,166,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,199,53,1)'></td>
+ <td width='1' style='background-color: rgba(159,199,73,1)'></td>
+ <td width='1' style='background-color: rgba(152,199,88,1)'></td>
+ <td width='1' style='background-color: rgba(145,199,100,1)'></td>
+ <td width='1' style='background-color: rgba(138,199,111,1)'></td>
+ <td width='1' style='background-color: rgba(130,199,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,199,130,1)'></td>
+ <td width='1' style='background-color: rgba(111,199,138,1)'></td>
+ <td width='1' style='background-color: rgba(100,199,145,1)'></td>
+ <td width='1' style='background-color: rgba(88,199,152,1)'></td>
+ <td width='1' style='background-color: rgba(73,199,159,1)'></td>
+ <td width='1' style='background-color: rgba(53,199,166,1)'></td>
+ <td width='1' style='background-color: rgba(0,199,172,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,194,53,1)'></td>
+ <td width='1' style='background-color: rgba(166,194,73,1)'></td>
+ <td width='1' style='background-color: rgba(159,194,88,1)'></td>
+ <td width='1' style='background-color: rgba(152,194,100,1)'></td>
+ <td width='1' style='background-color: rgba(145,194,111,1)'></td>
+ <td width='1' style='background-color: rgba(138,194,121,1)'></td>
+ <td width='1' style='background-color: rgba(130,194,130,1)'></td>
+ <td width='1' style='background-color: rgba(121,194,138,1)'></td>
+ <td width='1' style='background-color: rgba(111,194,145,1)'></td>
+ <td width='1' style='background-color: rgba(100,194,152,1)'></td>
+ <td width='1' style='background-color: rgba(88,194,159,1)'></td>
+ <td width='1' style='background-color: rgba(73,194,166,1)'></td>
+ <td width='1' style='background-color: rgba(53,194,172,1)'></td>
+ <td width='1' style='background-color: rgba(0,194,178,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,189,53,1)'></td>
+ <td width='1' style='background-color: rgba(172,189,73,1)'></td>
+ <td width='1' style='background-color: rgba(166,189,88,1)'></td>
+ <td width='1' style='background-color: rgba(159,189,100,1)'></td>
+ <td width='1' style='background-color: rgba(152,189,111,1)'></td>
+ <td width='1' style='background-color: rgba(145,189,121,1)'></td>
+ <td width='1' style='background-color: rgba(138,189,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,189,138,1)'></td>
+ <td width='1' style='background-color: rgba(121,189,145,1)'></td>
+ <td width='1' style='background-color: rgba(111,189,152,1)'></td>
+ <td width='1' style='background-color: rgba(100,189,159,1)'></td>
+ <td width='1' style='background-color: rgba(88,189,166,1)'></td>
+ <td width='1' style='background-color: rgba(73,189,172,1)'></td>
+ <td width='1' style='background-color: rgba(53,189,178,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,183,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,53,1)'></td>
+ <td width='1' style='background-color: rgba(178,183,73,1)'></td>
+ <td width='1' style='background-color: rgba(172,183,88,1)'></td>
+ <td width='1' style='background-color: rgba(166,183,100,1)'></td>
+ <td width='1' style='background-color: rgba(159,183,111,1)'></td>
+ <td width='1' style='background-color: rgba(152,183,121,1)'></td>
+ <td width='1' style='background-color: rgba(145,183,130,1)'></td>
+ <td width='1' style='background-color: rgba(138,183,138,1)'></td>
+ <td width='1' style='background-color: rgba(130,183,145,1)'></td>
+ <td width='1' style='background-color: rgba(121,183,152,1)'></td>
+ <td width='1' style='background-color: rgba(111,183,159,1)'></td>
+ <td width='1' style='background-color: rgba(100,183,166,1)'></td>
+ <td width='1' style='background-color: rgba(88,183,172,1)'></td>
+ <td width='1' style='background-color: rgba(73,183,178,1)'></td>
+ <td width='1' style='background-color: rgba(53,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,183,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,178,53,1)'></td>
+ <td width='1' style='background-color: rgba(183,178,73,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,88,1)'></td>
+ <td width='1' style='background-color: rgba(172,178,100,1)'></td>
+ <td width='1' style='background-color: rgba(166,178,111,1)'></td>
+ <td width='1' style='background-color: rgba(159,178,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,178,130,1)'></td>
+ <td width='1' style='background-color: rgba(145,178,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,178,145,1)'></td>
+ <td width='1' style='background-color: rgba(130,178,152,1)'></td>
+ <td width='1' style='background-color: rgba(121,178,159,1)'></td>
+ <td width='1' style='background-color: rgba(111,178,166,1)'></td>
+ <td width='1' style='background-color: rgba(100,178,172,1)'></td>
+ <td width='1' style='background-color: rgba(88,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(73,178,183,1)'></td>
+ <td width='1' style='background-color: rgba(53,178,189,1)'></td>
+ <td width='1' style='background-color: rgba(0,178,194,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,172,53,1)'></td>
+ <td width='1' style='background-color: rgba(189,172,73,1)'></td>
+ <td width='1' style='background-color: rgba(183,172,88,1)'></td>
+ <td width='1' style='background-color: rgba(178,172,100,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,111,1)'></td>
+ <td width='1' style='background-color: rgba(166,172,121,1)'></td>
+ <td width='1' style='background-color: rgba(159,172,130,1)'></td>
+ <td width='1' style='background-color: rgba(152,172,138,1)'></td>
+ <td width='1' style='background-color: rgba(145,172,145,1)'></td>
+ <td width='1' style='background-color: rgba(138,172,152,1)'></td>
+ <td width='1' style='background-color: rgba(130,172,159,1)'></td>
+ <td width='1' style='background-color: rgba(121,172,166,1)'></td>
+ <td width='1' style='background-color: rgba(111,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(100,172,178,1)'></td>
+ <td width='1' style='background-color: rgba(88,172,183,1)'></td>
+ <td width='1' style='background-color: rgba(73,172,189,1)'></td>
+ <td width='1' style='background-color: rgba(53,172,194,1)'></td>
+ <td width='1' style='background-color: rgba(0,172,199,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,166,53,1)'></td>
+ <td width='1' style='background-color: rgba(194,166,73,1)'></td>
+ <td width='1' style='background-color: rgba(189,166,88,1)'></td>
+ <td width='1' style='background-color: rgba(183,166,100,1)'></td>
+ <td width='1' style='background-color: rgba(178,166,111,1)'></td>
+ <td width='1' style='background-color: rgba(172,166,121,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,130,1)'></td>
+ <td width='1' style='background-color: rgba(159,166,138,1)'></td>
+ <td width='1' style='background-color: rgba(152,166,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,166,152,1)'></td>
+ <td width='1' style='background-color: rgba(138,166,159,1)'></td>
+ <td width='1' style='background-color: rgba(130,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(121,166,172,1)'></td>
+ <td width='1' style='background-color: rgba(111,166,178,1)'></td>
+ <td width='1' style='background-color: rgba(100,166,183,1)'></td>
+ <td width='1' style='background-color: rgba(88,166,189,1)'></td>
+ <td width='1' style='background-color: rgba(73,166,194,1)'></td>
+ <td width='1' style='background-color: rgba(53,166,199,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,204,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,159,53,1)'></td>
+ <td width='1' style='background-color: rgba(199,159,73,1)'></td>
+ <td width='1' style='background-color: rgba(194,159,88,1)'></td>
+ <td width='1' style='background-color: rgba(189,159,100,1)'></td>
+ <td width='1' style='background-color: rgba(183,159,111,1)'></td>
+ <td width='1' style='background-color: rgba(178,159,121,1)'></td>
+ <td width='1' style='background-color: rgba(172,159,130,1)'></td>
+ <td width='1' style='background-color: rgba(166,159,138,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,145,1)'></td>
+ <td width='1' style='background-color: rgba(152,159,152,1)'></td>
+ <td width='1' style='background-color: rgba(145,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(138,159,166,1)'></td>
+ <td width='1' style='background-color: rgba(130,159,172,1)'></td>
+ <td width='1' style='background-color: rgba(121,159,178,1)'></td>
+ <td width='1' style='background-color: rgba(111,159,183,1)'></td>
+ <td width='1' style='background-color: rgba(100,159,189,1)'></td>
+ <td width='1' style='background-color: rgba(88,159,194,1)'></td>
+ <td width='1' style='background-color: rgba(73,159,199,1)'></td>
+ <td width='1' style='background-color: rgba(53,159,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,159,209,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,152,53,1)'></td>
+ <td width='1' style='background-color: rgba(204,152,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,152,88,1)'></td>
+ <td width='1' style='background-color: rgba(194,152,100,1)'></td>
+ <td width='1' style='background-color: rgba(189,152,111,1)'></td>
+ <td width='1' style='background-color: rgba(183,152,121,1)'></td>
+ <td width='1' style='background-color: rgba(178,152,130,1)'></td>
+ <td width='1' style='background-color: rgba(172,152,138,1)'></td>
+ <td width='1' style='background-color: rgba(166,152,145,1)'></td>
+ <td width='1' style='background-color: rgba(159,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,159,1)'></td>
+ <td width='1' style='background-color: rgba(145,152,166,1)'></td>
+ <td width='1' style='background-color: rgba(138,152,172,1)'></td>
+ <td width='1' style='background-color: rgba(130,152,178,1)'></td>
+ <td width='1' style='background-color: rgba(121,152,183,1)'></td>
+ <td width='1' style='background-color: rgba(111,152,189,1)'></td>
+ <td width='1' style='background-color: rgba(100,152,194,1)'></td>
+ <td width='1' style='background-color: rgba(88,152,199,1)'></td>
+ <td width='1' style='background-color: rgba(73,152,204,1)'></td>
+ <td width='1' style='background-color: rgba(53,152,209,1)'></td>
+ <td width='1' style='background-color: rgba(0,152,214,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,145,53,1)'></td>
+ <td width='1' style='background-color: rgba(209,145,73,1)'></td>
+ <td width='1' style='background-color: rgba(204,145,88,1)'></td>
+ <td width='1' style='background-color: rgba(199,145,100,1)'></td>
+ <td width='1' style='background-color: rgba(194,145,111,1)'></td>
+ <td width='1' style='background-color: rgba(189,145,121,1)'></td>
+ <td width='1' style='background-color: rgba(183,145,130,1)'></td>
+ <td width='1' style='background-color: rgba(178,145,138,1)'></td>
+ <td width='1' style='background-color: rgba(172,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(166,145,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,145,159,1)'></td>
+ <td width='1' style='background-color: rgba(152,145,166,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,172,1)'></td>
+ <td width='1' style='background-color: rgba(138,145,178,1)'></td>
+ <td width='1' style='background-color: rgba(130,145,183,1)'></td>
+ <td width='1' style='background-color: rgba(121,145,189,1)'></td>
+ <td width='1' style='background-color: rgba(111,145,194,1)'></td>
+ <td width='1' style='background-color: rgba(100,145,199,1)'></td>
+ <td width='1' style='background-color: rgba(88,145,204,1)'></td>
+ <td width='1' style='background-color: rgba(73,145,209,1)'></td>
+ <td width='1' style='background-color: rgba(53,145,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,218,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,138,53,1)'></td>
+ <td width='1' style='background-color: rgba(214,138,73,1)'></td>
+ <td width='1' style='background-color: rgba(209,138,88,1)'></td>
+ <td width='1' style='background-color: rgba(204,138,100,1)'></td>
+ <td width='1' style='background-color: rgba(199,138,111,1)'></td>
+ <td width='1' style='background-color: rgba(194,138,121,1)'></td>
+ <td width='1' style='background-color: rgba(189,138,130,1)'></td>
+ <td width='1' style='background-color: rgba(183,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(178,138,145,1)'></td>
+ <td width='1' style='background-color: rgba(172,138,152,1)'></td>
+ <td width='1' style='background-color: rgba(166,138,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,138,166,1)'></td>
+ <td width='1' style='background-color: rgba(152,138,172,1)'></td>
+ <td width='1' style='background-color: rgba(145,138,178,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,183,1)'></td>
+ <td width='1' style='background-color: rgba(130,138,189,1)'></td>
+ <td width='1' style='background-color: rgba(121,138,194,1)'></td>
+ <td width='1' style='background-color: rgba(111,138,199,1)'></td>
+ <td width='1' style='background-color: rgba(100,138,204,1)'></td>
+ <td width='1' style='background-color: rgba(88,138,209,1)'></td>
+ <td width='1' style='background-color: rgba(73,138,214,1)'></td>
+ <td width='1' style='background-color: rgba(53,138,218,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,130,53,1)'></td>
+ <td width='1' style='background-color: rgba(218,130,73,1)'></td>
+ <td width='1' style='background-color: rgba(214,130,88,1)'></td>
+ <td width='1' style='background-color: rgba(209,130,100,1)'></td>
+ <td width='1' style='background-color: rgba(204,130,111,1)'></td>
+ <td width='1' style='background-color: rgba(199,130,121,1)'></td>
+ <td width='1' style='background-color: rgba(194,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(189,130,138,1)'></td>
+ <td width='1' style='background-color: rgba(183,130,145,1)'></td>
+ <td width='1' style='background-color: rgba(178,130,152,1)'></td>
+ <td width='1' style='background-color: rgba(172,130,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,130,166,1)'></td>
+ <td width='1' style='background-color: rgba(159,130,172,1)'></td>
+ <td width='1' style='background-color: rgba(152,130,178,1)'></td>
+ <td width='1' style='background-color: rgba(145,130,183,1)'></td>
+ <td width='1' style='background-color: rgba(138,130,189,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,194,1)'></td>
+ <td width='1' style='background-color: rgba(121,130,199,1)'></td>
+ <td width='1' style='background-color: rgba(111,130,204,1)'></td>
+ <td width='1' style='background-color: rgba(100,130,209,1)'></td>
+ <td width='1' style='background-color: rgba(88,130,214,1)'></td>
+ <td width='1' style='background-color: rgba(73,130,218,1)'></td>
+ <td width='1' style='background-color: rgba(53,130,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,130,227,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,121,53,1)'></td>
+ <td width='1' style='background-color: rgba(223,121,73,1)'></td>
+ <td width='1' style='background-color: rgba(218,121,88,1)'></td>
+ <td width='1' style='background-color: rgba(214,121,100,1)'></td>
+ <td width='1' style='background-color: rgba(209,121,111,1)'></td>
+ <td width='1' style='background-color: rgba(204,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(199,121,130,1)'></td>
+ <td width='1' style='background-color: rgba(194,121,138,1)'></td>
+ <td width='1' style='background-color: rgba(189,121,145,1)'></td>
+ <td width='1' style='background-color: rgba(183,121,152,1)'></td>
+ <td width='1' style='background-color: rgba(178,121,159,1)'></td>
+ <td width='1' style='background-color: rgba(172,121,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,121,172,1)'></td>
+ <td width='1' style='background-color: rgba(159,121,178,1)'></td>
+ <td width='1' style='background-color: rgba(152,121,183,1)'></td>
+ <td width='1' style='background-color: rgba(145,121,189,1)'></td>
+ <td width='1' style='background-color: rgba(138,121,194,1)'></td>
+ <td width='1' style='background-color: rgba(130,121,199,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,204,1)'></td>
+ <td width='1' style='background-color: rgba(111,121,209,1)'></td>
+ <td width='1' style='background-color: rgba(100,121,214,1)'></td>
+ <td width='1' style='background-color: rgba(88,121,218,1)'></td>
+ <td width='1' style='background-color: rgba(73,121,223,1)'></td>
+ <td width='1' style='background-color: rgba(53,121,227,1)'></td>
+ <td width='1' style='background-color: rgba(0,121,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,111,53,1)'></td>
+ <td width='1' style='background-color: rgba(227,111,73,1)'></td>
+ <td width='1' style='background-color: rgba(223,111,88,1)'></td>
+ <td width='1' style='background-color: rgba(218,111,100,1)'></td>
+ <td width='1' style='background-color: rgba(214,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(209,111,121,1)'></td>
+ <td width='1' style='background-color: rgba(204,111,130,1)'></td>
+ <td width='1' style='background-color: rgba(199,111,138,1)'></td>
+ <td width='1' style='background-color: rgba(194,111,145,1)'></td>
+ <td width='1' style='background-color: rgba(189,111,152,1)'></td>
+ <td width='1' style='background-color: rgba(183,111,159,1)'></td>
+ <td width='1' style='background-color: rgba(178,111,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,111,172,1)'></td>
+ <td width='1' style='background-color: rgba(166,111,178,1)'></td>
+ <td width='1' style='background-color: rgba(159,111,183,1)'></td>
+ <td width='1' style='background-color: rgba(152,111,189,1)'></td>
+ <td width='1' style='background-color: rgba(145,111,194,1)'></td>
+ <td width='1' style='background-color: rgba(138,111,199,1)'></td>
+ <td width='1' style='background-color: rgba(130,111,204,1)'></td>
+ <td width='1' style='background-color: rgba(121,111,209,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,214,1)'></td>
+ <td width='1' style='background-color: rgba(100,111,218,1)'></td>
+ <td width='1' style='background-color: rgba(88,111,223,1)'></td>
+ <td width='1' style='background-color: rgba(73,111,227,1)'></td>
+ <td width='1' style='background-color: rgba(53,111,231,1)'></td>
+ <td width='1' style='background-color: rgba(0,111,235,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,100,53,1)'></td>
+ <td width='1' style='background-color: rgba(231,100,73,1)'></td>
+ <td width='1' style='background-color: rgba(227,100,88,1)'></td>
+ <td width='1' style='background-color: rgba(223,100,100,1)'></td>
+ <td width='1' style='background-color: rgba(218,100,111,1)'></td>
+ <td width='1' style='background-color: rgba(214,100,121,1)'></td>
+ <td width='1' style='background-color: rgba(209,100,130,1)'></td>
+ <td width='1' style='background-color: rgba(204,100,138,1)'></td>
+ <td width='1' style='background-color: rgba(199,100,145,1)'></td>
+ <td width='1' style='background-color: rgba(194,100,152,1)'></td>
+ <td width='1' style='background-color: rgba(189,100,159,1)'></td>
+ <td width='1' style='background-color: rgba(183,100,166,1)'></td>
+ <td width='1' style='background-color: rgba(178,100,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,100,178,1)'></td>
+ <td width='1' style='background-color: rgba(166,100,183,1)'></td>
+ <td width='1' style='background-color: rgba(159,100,189,1)'></td>
+ <td width='1' style='background-color: rgba(152,100,194,1)'></td>
+ <td width='1' style='background-color: rgba(145,100,199,1)'></td>
+ <td width='1' style='background-color: rgba(138,100,204,1)'></td>
+ <td width='1' style='background-color: rgba(130,100,209,1)'></td>
+ <td width='1' style='background-color: rgba(121,100,214,1)'></td>
+ <td width='1' style='background-color: rgba(111,100,218,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,223,1)'></td>
+ <td width='1' style='background-color: rgba(88,100,227,1)'></td>
+ <td width='1' style='background-color: rgba(73,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(53,100,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,100,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,88,53,1)'></td>
+ <td width='1' style='background-color: rgba(235,88,73,1)'></td>
+ <td width='1' style='background-color: rgba(231,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(227,88,100,1)'></td>
+ <td width='1' style='background-color: rgba(223,88,111,1)'></td>
+ <td width='1' style='background-color: rgba(218,88,121,1)'></td>
+ <td width='1' style='background-color: rgba(214,88,130,1)'></td>
+ <td width='1' style='background-color: rgba(209,88,138,1)'></td>
+ <td width='1' style='background-color: rgba(204,88,145,1)'></td>
+ <td width='1' style='background-color: rgba(199,88,152,1)'></td>
+ <td width='1' style='background-color: rgba(194,88,159,1)'></td>
+ <td width='1' style='background-color: rgba(189,88,166,1)'></td>
+ <td width='1' style='background-color: rgba(183,88,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,88,178,1)'></td>
+ <td width='1' style='background-color: rgba(172,88,183,1)'></td>
+ <td width='1' style='background-color: rgba(166,88,189,1)'></td>
+ <td width='1' style='background-color: rgba(159,88,194,1)'></td>
+ <td width='1' style='background-color: rgba(152,88,199,1)'></td>
+ <td width='1' style='background-color: rgba(145,88,204,1)'></td>
+ <td width='1' style='background-color: rgba(138,88,209,1)'></td>
+ <td width='1' style='background-color: rgba(130,88,214,1)'></td>
+ <td width='1' style='background-color: rgba(121,88,218,1)'></td>
+ <td width='1' style='background-color: rgba(111,88,223,1)'></td>
+ <td width='1' style='background-color: rgba(100,88,227,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,231,1)'></td>
+ <td width='1' style='background-color: rgba(73,88,235,1)'></td>
+ <td width='1' style='background-color: rgba(53,88,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,243,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,73,53,1)'></td>
+ <td width='1' style='background-color: rgba(239,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(235,73,88,1)'></td>
+ <td width='1' style='background-color: rgba(231,73,100,1)'></td>
+ <td width='1' style='background-color: rgba(227,73,111,1)'></td>
+ <td width='1' style='background-color: rgba(223,73,121,1)'></td>
+ <td width='1' style='background-color: rgba(218,73,130,1)'></td>
+ <td width='1' style='background-color: rgba(214,73,138,1)'></td>
+ <td width='1' style='background-color: rgba(209,73,145,1)'></td>
+ <td width='1' style='background-color: rgba(204,73,152,1)'></td>
+ <td width='1' style='background-color: rgba(199,73,159,1)'></td>
+ <td width='1' style='background-color: rgba(194,73,166,1)'></td>
+ <td width='1' style='background-color: rgba(189,73,172,1)'></td>
+ <td width='1' style='background-color: rgba(183,73,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,73,183,1)'></td>
+ <td width='1' style='background-color: rgba(172,73,189,1)'></td>
+ <td width='1' style='background-color: rgba(166,73,194,1)'></td>
+ <td width='1' style='background-color: rgba(159,73,199,1)'></td>
+ <td width='1' style='background-color: rgba(152,73,204,1)'></td>
+ <td width='1' style='background-color: rgba(145,73,209,1)'></td>
+ <td width='1' style='background-color: rgba(138,73,214,1)'></td>
+ <td width='1' style='background-color: rgba(130,73,218,1)'></td>
+ <td width='1' style='background-color: rgba(121,73,223,1)'></td>
+ <td width='1' style='background-color: rgba(111,73,227,1)'></td>
+ <td width='1' style='background-color: rgba(100,73,231,1)'></td>
+ <td width='1' style='background-color: rgba(88,73,235,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,239,1)'></td>
+ <td width='1' style='background-color: rgba(53,73,243,1)'></td>
+ <td width='1' style='background-color: rgba(0,73,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,53,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,53,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(243,53,73,1)'></td>
+ <td width='1' style='background-color: rgba(239,53,88,1)'></td>
+ <td width='1' style='background-color: rgba(235,53,100,1)'></td>
+ <td width='1' style='background-color: rgba(231,53,111,1)'></td>
+ <td width='1' style='background-color: rgba(227,53,121,1)'></td>
+ <td width='1' style='background-color: rgba(223,53,130,1)'></td>
+ <td width='1' style='background-color: rgba(218,53,138,1)'></td>
+ <td width='1' style='background-color: rgba(214,53,145,1)'></td>
+ <td width='1' style='background-color: rgba(209,53,152,1)'></td>
+ <td width='1' style='background-color: rgba(204,53,159,1)'></td>
+ <td width='1' style='background-color: rgba(199,53,166,1)'></td>
+ <td width='1' style='background-color: rgba(194,53,172,1)'></td>
+ <td width='1' style='background-color: rgba(189,53,178,1)'></td>
+ <td width='1' style='background-color: rgba(183,53,183,1)'></td>
+ <td width='1' style='background-color: rgba(178,53,189,1)'></td>
+ <td width='1' style='background-color: rgba(172,53,194,1)'></td>
+ <td width='1' style='background-color: rgba(166,53,199,1)'></td>
+ <td width='1' style='background-color: rgba(159,53,204,1)'></td>
+ <td width='1' style='background-color: rgba(152,53,209,1)'></td>
+ <td width='1' style='background-color: rgba(145,53,214,1)'></td>
+ <td width='1' style='background-color: rgba(138,53,218,1)'></td>
+ <td width='1' style='background-color: rgba(130,53,223,1)'></td>
+ <td width='1' style='background-color: rgba(121,53,227,1)'></td>
+ <td width='1' style='background-color: rgba(111,53,231,1)'></td>
+ <td width='1' style='background-color: rgba(100,53,235,1)'></td>
+ <td width='1' style='background-color: rgba(88,53,239,1)'></td>
+ <td width='1' style='background-color: rgba(73,53,243,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,251,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,53,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,73,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,88,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,100,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,111,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,121,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,130,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,138,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,145,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,152,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,159,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,166,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,172,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,178,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,189,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,194,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,199,1)'></td>
+ <td width='1' style='background-color: rgba(166,0,204,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,209,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,214,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,218,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,223,1)'></td>
+ <td width='1' style='background-color: rgba(130,0,227,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,231,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,235,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,239,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,243,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,251,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-chunkorder/grayscale.html b/image/test/reftest/pngsuite-chunkorder/grayscale.html
new file mode 100644
index 0000000000..fc18c727be
--- /dev/null
+++ b/image/test/reftest/pngsuite-chunkorder/grayscale.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(104,104,104,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(83,83,83,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,100,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(108,108,108,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(104,104,104,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(83,83,83,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,100,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(108,108,108,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(104,104,104,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(97,97,97,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(65,65,65,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(49,49,49,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-chunkorder/oi1n0g16.png b/image/test/reftest/pngsuite-chunkorder/oi1n0g16.png
new file mode 100644
index 0000000000..e7c82f78eb
--- /dev/null
+++ b/image/test/reftest/pngsuite-chunkorder/oi1n0g16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-chunkorder/oi1n2c16.png b/image/test/reftest/pngsuite-chunkorder/oi1n2c16.png
new file mode 100644
index 0000000000..50c1cb91a0
--- /dev/null
+++ b/image/test/reftest/pngsuite-chunkorder/oi1n2c16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-chunkorder/oi2n0g16.png b/image/test/reftest/pngsuite-chunkorder/oi2n0g16.png
new file mode 100644
index 0000000000..14d64c583d
--- /dev/null
+++ b/image/test/reftest/pngsuite-chunkorder/oi2n0g16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-chunkorder/oi2n2c16.png b/image/test/reftest/pngsuite-chunkorder/oi2n2c16.png
new file mode 100644
index 0000000000..4c2e3e3352
--- /dev/null
+++ b/image/test/reftest/pngsuite-chunkorder/oi2n2c16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-chunkorder/oi4n0g16.png b/image/test/reftest/pngsuite-chunkorder/oi4n0g16.png
new file mode 100644
index 0000000000..69e73ede31
--- /dev/null
+++ b/image/test/reftest/pngsuite-chunkorder/oi4n0g16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-chunkorder/oi4n2c16.png b/image/test/reftest/pngsuite-chunkorder/oi4n2c16.png
new file mode 100644
index 0000000000..93691e373a
--- /dev/null
+++ b/image/test/reftest/pngsuite-chunkorder/oi4n2c16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-chunkorder/oi9n0g16.png b/image/test/reftest/pngsuite-chunkorder/oi9n0g16.png
new file mode 100644
index 0000000000..9248413576
--- /dev/null
+++ b/image/test/reftest/pngsuite-chunkorder/oi9n0g16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-chunkorder/oi9n2c16.png b/image/test/reftest/pngsuite-chunkorder/oi9n2c16.png
new file mode 100644
index 0000000000..f0512e49f2
--- /dev/null
+++ b/image/test/reftest/pngsuite-chunkorder/oi9n2c16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-chunkorder/reftest.list b/image/test/reftest/pngsuite-chunkorder/reftest.list
new file mode 100644
index 0000000000..2e161d0d39
--- /dev/null
+++ b/image/test/reftest/pngsuite-chunkorder/reftest.list
@@ -0,0 +1,21 @@
+# PngSuite - Chunk ordering
+#
+# The resulting images of a type (color or grayscale) should all look the
+# same, so they share common HTML reference files.
+
+# oi1n0g16 - grayscale mother image with 1 idat-chunk
+== oi1n0g16.png grayscale.html
+# oi1n2c16 - color mother image with 1 idat-chunk
+== oi1n2c16.png color.html
+# oi2n0g16 - grayscale image with 2 idat-chunks
+== oi2n0g16.png grayscale.html
+# oi2n2c16 - color image with 2 idat-chunks
+== oi2n2c16.png color.html
+# oi4n0g16 - grayscale image with 4 unequal sized idat-chunks
+== oi4n0g16.png grayscale.html
+# oi4n2c16 - color image with 4 unequal sized idat-chunks
+== oi4n2c16.png color.html
+# oi9n0g16 - grayscale image with all idat-chunks length one
+== oi9n0g16.png grayscale.html
+# oi9n2c16 - color image with all idat-chunks length one
+== oi9n2c16.png color.html
diff --git a/image/test/reftest/pngsuite-corrupted/reftest.list b/image/test/reftest/pngsuite-corrupted/reftest.list
new file mode 100644
index 0000000000..86c5880f2c
--- /dev/null
+++ b/image/test/reftest/pngsuite-corrupted/reftest.list
@@ -0,0 +1,10 @@
+# PngSuite - Corrupted files
+#
+# Note: these are corrupt files, and so no image should be rendered.
+
+# x00n0g01 - empty 0x0 grayscale file
+== wrapper.html?x00n0g01.png about:blank
+# xcrn0g04 - added cr bytes
+== wrapper.html?xcrn0g04.png about:blank
+# xlfn0g04 - added lf bytes
+== wrapper.html?xlfn0g04.png about:blank
diff --git a/image/test/reftest/pngsuite-corrupted/wrapper.html b/image/test/reftest/pngsuite-corrupted/wrapper.html
new file mode 100644
index 0000000000..45b5167754
--- /dev/null
+++ b/image/test/reftest/pngsuite-corrupted/wrapper.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<head>
+<title>Image reftest wrapper</title>
+<style type="text/css">
+ #image1 { background-color: rgb(10, 100, 250); }
+</style>
+<script>
+ // The image is loaded async after the page loads
+ // wait for it to finish loading
+ function onImageLoad() {
+ document.documentElement.removeAttribute("class");
+ };
+</script>
+</head>
+<body>
+<!-- non-empty alt to avoid the broken image icon -->
+<img id="image1" alt=" ">
+<script>
+ // Use as "wrapper.html?image.png
+ var imgURL = document.location.search.substr(1);
+ document.images[0].onload = onImageLoad;
+ document.images[0].onerror = onImageLoad;
+ document.images[0].src = imgURL;
+</script>
+</body>
+</html>
+
diff --git a/image/test/reftest/pngsuite-corrupted/x00n0g01.png b/image/test/reftest/pngsuite-corrupted/x00n0g01.png
new file mode 100644
index 0000000000..db3a5fda7e
--- /dev/null
+++ b/image/test/reftest/pngsuite-corrupted/x00n0g01.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-corrupted/xcrn0g04.png b/image/test/reftest/pngsuite-corrupted/xcrn0g04.png
new file mode 100644
index 0000000000..5bce9f3ada
--- /dev/null
+++ b/image/test/reftest/pngsuite-corrupted/xcrn0g04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-corrupted/xlfn0g04.png b/image/test/reftest/pngsuite-corrupted/xlfn0g04.png
new file mode 100644
index 0000000000..1fd104ba61
--- /dev/null
+++ b/image/test/reftest/pngsuite-corrupted/xlfn0g04.png
@@ -0,0 +1,13 @@
+‰PNG
+
+
+
+
+
+IHDR “áÈ)ÈIDATxœ]ÑÁ
+Â0 P*@ð¡#°
+
+#TâÈ10lPF`Ø F=•ŸÄIQâ*çÅuí”`%qk
+Hžñšˆ©ñ´€m÷Íüµàߟ Ñ=,¸fìOK
+
+ç ÐtŽÀ(Èïä’צíF ;èPº€¯¾{xpç]9‡/p*$(ì*éyìÕƒ ×þÚéçè@÷C¼  cÔqž‹NÛU#„)11·.räðfä0°ägh(¥týÙÂEøÿ‰kIEND®B`‚ \ No newline at end of file
diff --git a/image/test/reftest/pngsuite-filtering/f00n0g08.html b/image/test/reftest/pngsuite-filtering/f00n0g08.html
new file mode 100644
index 0000000000..3df624891b
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f00n0g08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-filtering/f00n0g08.png b/image/test/reftest/pngsuite-filtering/f00n0g08.png
new file mode 100644
index 0000000000..45a0075967
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f00n0g08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-filtering/f00n2c08.html b/image/test/reftest/pngsuite-filtering/f00n2c08.html
new file mode 100644
index 0000000000..2e5f1e1868
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f00n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,8,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,16,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,24,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,32,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,41,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,49,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,57,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,65,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,82,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,90,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,106,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,148,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,29,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,31,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,38,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,45,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,52,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,59,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,67,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,81,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,88,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,96,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,103,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,110,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,117,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,124,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,132,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,153,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,161,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,175,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,55,7,1)'></td>
+ <td width='1' style='background-color: rgba(238,59,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,63,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,69,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,75,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,81,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,87,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,93,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,100,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,106,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,112,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,118,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,124,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,137,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,143,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,149,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(208,77,6,1)'></td>
+ <td width='1' style='background-color: rgba(223,83,7,1)'></td>
+ <td width='1' style='background-color: rgba(238,88,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,95,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,100,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,110,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,120,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,125,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,141,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,167,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,187,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,208,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(193,96,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,103,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,111,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,118,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,127,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,143,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,147,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,160,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,176,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,184,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,201,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(179,111,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,120,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,129,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,139,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,148,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,165,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,171,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,196,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,208,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,214,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,220,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,215,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,124,4,1)'></td>
+ <td width='1' style='background-color: rgba(179,134,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,144,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,155,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,167,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,178,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,191,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,195,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,201,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,207,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,215,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(152,133,4,1)'></td>
+ <td width='1' style='background-color: rgba(165,145,4,1)'></td>
+ <td width='1' style='background-color: rgba(179,156,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,169,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,181,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,195,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,208,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,225,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,231,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,235,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,237,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,243,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,244,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,198,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,14,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,22,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,30,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,94,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,182,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,190,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(112,128,3,1)'></td>
+ <td width='1' style='background-color: rgba(123,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(134,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(145,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(157,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(169,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(182,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(196,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(209,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(225,255,14,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,94,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(244,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,182,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(88,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(96,128,3,1)'></td>
+ <td width='1' style='background-color: rgba(105,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(115,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(124,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(135,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(145,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(156,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(168,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(179,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(200,255,38,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,46,1)'></td>
+ <td width='1' style='background-color: rgba(204,255,54,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,62,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,94,1)'></td>
+ <td width='1' style='background-color: rgba(216,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(220,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,174,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(66,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(73,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(80,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(88,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(95,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(104,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(112,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(121,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(130,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(140,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(149,238,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,29,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,37,1)'></td>
+ <td width='1' style='background-color: rgba(175,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(196,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(215,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,166,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(48,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(53,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(58,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(64,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(70,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(76,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(83,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(90,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(97,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(104,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(112,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,13,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,29,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,37,1)'></td>
+ <td width='1' style='background-color: rgba(148,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(177,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(185,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(201,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,158,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(32,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(36,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(39,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(44,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(48,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(52,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(57,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(62,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(67,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(72,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(78,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,5,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,13,1)'></td>
+ <td width='1' style='background-color: rgba(106,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,29,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(142,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(157,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(162,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(167,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,150,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(19,76,1,1)'></td>
+ <td width='1' style='background-color: rgba(21,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(24,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(26,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(29,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(32,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(35,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(38,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(41,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(45,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(48,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(59,238,4,1)'></td>
+ <td width='1' style='background-color: rgba(64,255,5,1)'></td>
+ <td width='1' style='background-color: rgba(70,255,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(113,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(119,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(131,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(150,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(162,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,142,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(8,67,1,1)'></td>
+ <td width='1' style='background-color: rgba(9,76,1,1)'></td>
+ <td width='1' style='background-color: rgba(10,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(12,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(13,106,1,1)'></td>
+ <td width='1' style='background-color: rgba(14,117,1,1)'></td>
+ <td width='1' style='background-color: rgba(16,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(17,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(19,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(20,165,2,1)'></td>
+ <td width='1' style='background-color: rgba(22,179,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,223,3,1)'></td>
+ <td width='1' style='background-color: rgba(29,238,3,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,255,28,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,52,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,60,1)'></td>
+ <td width='1' style='background-color: rgba(89,255,68,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,76,1)'></td>
+ <td width='1' style='background-color: rgba(103,255,84,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(118,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(139,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,133,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,67,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,128,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,208,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(12,255,8,1)'></td>
+ <td width='1' style='background-color: rgba(20,255,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(44,255,41,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,49,1)'></td>
+ <td width='1' style='background-color: rgba(60,255,57,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,65,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,82,1)'></td>
+ <td width='1' style='background-color: rgba(93,255,90,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,106,1)'></td>
+ <td width='1' style='background-color: rgba(117,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,123,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,52,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,7,1)'></td>
+ <td width='1' style='background-color: rgba(1,67,8,1)'></td>
+ <td width='1' style='background-color: rgba(1,76,9,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,10,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,11,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,12,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,14,1)'></td>
+ <td width='1' style='background-color: rgba(2,128,15,1)'></td>
+ <td width='1' style='background-color: rgba(2,140,17,1)'></td>
+ <td width='1' style='background-color: rgba(2,152,18,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,238,29,1)'></td>
+ <td width='1' style='background-color: rgba(4,255,31,1)'></td>
+ <td width='1' style='background-color: rgba(12,255,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(36,255,59,1)'></td>
+ <td width='1' style='background-color: rgba(44,255,67,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(60,255,81,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,88,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,96,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,103,1)'></td>
+ <td width='1' style='background-color: rgba(93,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(117,255,132,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,44,11,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,12,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,18,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,21,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,23,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,26,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,28,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,31,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,34,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,208,51,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,55,1)'></td>
+ <td width='1' style='background-color: rgba(2,238,59,1)'></td>
+ <td width='1' style='background-color: rgba(3,255,63,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,81,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,87,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,100,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,106,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,112,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,137,1)'></td>
+ <td width='1' style='background-color: rgba(108,255,143,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,38,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,28,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,32,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,35,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,39,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,43,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,47,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,66,1)'></td>
+ <td width='1' style='background-color: rgba(2,193,72,1)'></td>
+ <td width='1' style='background-color: rgba(2,208,77,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,83,1)'></td>
+ <td width='1' style='background-color: rgba(2,238,88,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,120,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,141,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,146,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,156,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,32,15,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,29,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,38,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,42,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,47,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,52,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,58,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,76,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,82,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,89,1)'></td>
+ <td width='1' style='background-color: rgba(2,193,96,1)'></td>
+ <td width='1' style='background-color: rgba(2,208,103,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,139,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,143,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,147,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,160,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,164,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,172,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,26,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,20,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,23,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,27,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,37,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,42,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,47,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,53,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,59,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,66,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,95,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,103,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,111,1)'></td>
+ <td width='1' style='background-color: rgba(2,193,120,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,162,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,165,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,171,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,177,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,21,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,24,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,28,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,50,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,57,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,64,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,71,1)'></td>
+ <td width='1' style='background-color: rgba(0,106,79,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,167,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,178,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,191,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,193,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,195,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,197,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,199,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,201,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,203,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,205,1)'></td>
+ <td width='1' style='background-color: rgba(67,255,207,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,209,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,16,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,18,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,23,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,28,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,39,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,45,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,75,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,83,1)'></td>
+ <td width='1' style='background-color: rgba(0,106,92,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,193,169,1)'></td>
+ <td width='1' style='background-color: rgba(1,208,181,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,195,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,208,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,225,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,226,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(67,255,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(1,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(1,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(1,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,8,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,11,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,18,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,23,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,45,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,75,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,84,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,93,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,134,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,157,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,169,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,182,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,196,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,225,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(41,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(50,230,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,4,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,7,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,51,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,57,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,72,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,79,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,96,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,115,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,124,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,135,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,156,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,179,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,196,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,200,255,1)'></td>
+ <td width='1' style='background-color: rgba(41,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,2,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,20,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,23,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,37,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,42,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,60,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,66,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,73,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,80,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,104,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,121,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,130,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,149,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,160,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,169,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,172,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,1,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,34,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,43,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,58,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,70,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,83,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,90,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,97,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,104,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,119,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,132,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,25,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,36,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,57,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,62,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,72,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,78,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,84,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,89,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,96,255,1)'></td>
+ <td width='1' style='background-color: rgba(8,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(16,106,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,11,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,17,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,35,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,41,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,45,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,56,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,255,1)'></td>
+ <td width='1' style='background-color: rgba(8,70,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,7,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,17,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,20,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-filtering/f00n2c08.png b/image/test/reftest/pngsuite-filtering/f00n2c08.png
new file mode 100644
index 0000000000..d6a1ffff62
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f00n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-filtering/f01n0g08.html b/image/test/reftest/pngsuite-filtering/f01n0g08.html
new file mode 100644
index 0000000000..2e056ecb9f
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f01n0g08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-filtering/f01n0g08.png b/image/test/reftest/pngsuite-filtering/f01n0g08.png
new file mode 100644
index 0000000000..4a1107b463
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f01n0g08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-filtering/f01n2c08.html b/image/test/reftest/pngsuite-filtering/f01n2c08.html
new file mode 100644
index 0000000000..25c4fe0446
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f01n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,8,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,16,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,24,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,32,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,41,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,49,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,57,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,65,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,82,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,90,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,106,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,148,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,29,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,31,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,38,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,45,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,52,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,59,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,67,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,81,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,88,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,96,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,103,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,110,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,117,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,124,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,132,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,153,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,161,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,175,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,55,7,1)'></td>
+ <td width='1' style='background-color: rgba(238,59,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,63,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,69,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,75,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,81,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,87,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,93,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,100,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,106,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,112,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,118,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,124,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,137,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,143,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,149,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(208,77,6,1)'></td>
+ <td width='1' style='background-color: rgba(223,83,7,1)'></td>
+ <td width='1' style='background-color: rgba(238,88,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,95,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,100,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,110,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,120,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,125,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,141,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,167,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,187,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,208,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(193,96,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,103,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,111,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,118,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,127,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,143,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,147,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,160,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,176,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,184,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,201,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(179,111,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,120,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,129,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,139,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,148,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,165,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,171,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,196,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,208,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,214,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,220,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,215,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,124,4,1)'></td>
+ <td width='1' style='background-color: rgba(179,134,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,144,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,155,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,167,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,178,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,191,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,195,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,201,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,207,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,215,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(152,133,4,1)'></td>
+ <td width='1' style='background-color: rgba(165,145,4,1)'></td>
+ <td width='1' style='background-color: rgba(179,156,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,169,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,181,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,195,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,208,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,225,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,231,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,235,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,237,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,243,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,244,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,198,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,14,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,22,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,30,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,38,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,54,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,86,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,94,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,182,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,190,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(112,128,3,1)'></td>
+ <td width='1' style='background-color: rgba(123,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(134,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(145,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(157,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(169,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(182,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(196,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(209,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(225,255,14,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,22,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,30,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,70,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,78,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,86,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,94,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(244,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,182,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(88,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(96,128,3,1)'></td>
+ <td width='1' style='background-color: rgba(105,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(115,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(124,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(135,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(145,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(156,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(168,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(179,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,14,1)'></td>
+ <td width='1' style='background-color: rgba(196,255,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,62,1)'></td>
+ <td width='1' style='background-color: rgba(208,255,70,1)'></td>
+ <td width='1' style='background-color: rgba(210,255,78,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,86,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,94,1)'></td>
+ <td width='1' style='background-color: rgba(216,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(220,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,174,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(66,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(73,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(80,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(88,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(95,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(104,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(112,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(121,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(130,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(140,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(149,238,4,1)'></td>
+ <td width='1' style='background-color: rgba(160,255,5,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(184,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(187,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(196,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(215,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,166,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(48,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(53,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(58,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(64,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(70,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(76,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(83,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(90,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(97,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(104,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(112,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(160,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(177,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(185,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(201,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,158,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(32,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(36,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(39,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(44,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(48,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(52,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(57,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(62,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(67,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(72,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(78,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,5,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(116,255,37,1)'></td>
+ <td width='1' style='background-color: rgba(121,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(126,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(131,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(142,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(157,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(162,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(167,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,150,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(19,76,1,1)'></td>
+ <td width='1' style='background-color: rgba(21,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(24,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(26,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(29,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(32,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(35,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(38,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(41,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(45,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(48,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(52,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(56,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(59,238,4,1)'></td>
+ <td width='1' style='background-color: rgba(64,255,5,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,29,1)'></td>
+ <td width='1' style='background-color: rgba(88,255,37,1)'></td>
+ <td width='1' style='background-color: rgba(94,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(107,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(113,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(119,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(131,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(150,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(162,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,142,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(8,67,1,1)'></td>
+ <td width='1' style='background-color: rgba(9,76,1,1)'></td>
+ <td width='1' style='background-color: rgba(10,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(12,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(13,106,1,1)'></td>
+ <td width='1' style='background-color: rgba(14,117,1,1)'></td>
+ <td width='1' style='background-color: rgba(16,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(17,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(19,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(20,165,2,1)'></td>
+ <td width='1' style='background-color: rgba(22,179,2,1)'></td>
+ <td width='1' style='background-color: rgba(24,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(26,208,3,1)'></td>
+ <td width='1' style='background-color: rgba(28,223,3,1)'></td>
+ <td width='1' style='background-color: rgba(29,238,3,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(46,255,20,1)'></td>
+ <td width='1' style='background-color: rgba(53,255,28,1)'></td>
+ <td width='1' style='background-color: rgba(60,255,36,1)'></td>
+ <td width='1' style='background-color: rgba(67,255,44,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,52,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,60,1)'></td>
+ <td width='1' style='background-color: rgba(89,255,68,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,76,1)'></td>
+ <td width='1' style='background-color: rgba(103,255,84,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(118,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(139,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,133,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,67,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,128,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,193,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,208,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(12,255,8,1)'></td>
+ <td width='1' style='background-color: rgba(20,255,16,1)'></td>
+ <td width='1' style='background-color: rgba(28,255,24,1)'></td>
+ <td width='1' style='background-color: rgba(36,255,32,1)'></td>
+ <td width='1' style='background-color: rgba(44,255,41,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,49,1)'></td>
+ <td width='1' style='background-color: rgba(60,255,57,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,65,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,82,1)'></td>
+ <td width='1' style='background-color: rgba(93,255,90,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,106,1)'></td>
+ <td width='1' style='background-color: rgba(117,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,123,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,52,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,7,1)'></td>
+ <td width='1' style='background-color: rgba(1,67,8,1)'></td>
+ <td width='1' style='background-color: rgba(1,76,9,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,10,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,11,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,12,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,14,1)'></td>
+ <td width='1' style='background-color: rgba(2,128,15,1)'></td>
+ <td width='1' style='background-color: rgba(2,140,17,1)'></td>
+ <td width='1' style='background-color: rgba(2,152,18,1)'></td>
+ <td width='1' style='background-color: rgba(2,165,20,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,21,1)'></td>
+ <td width='1' style='background-color: rgba(3,193,23,1)'></td>
+ <td width='1' style='background-color: rgba(3,208,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(4,255,31,1)'></td>
+ <td width='1' style='background-color: rgba(12,255,38,1)'></td>
+ <td width='1' style='background-color: rgba(20,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(28,255,52,1)'></td>
+ <td width='1' style='background-color: rgba(36,255,59,1)'></td>
+ <td width='1' style='background-color: rgba(44,255,67,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(60,255,81,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,88,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,96,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,103,1)'></td>
+ <td width='1' style='background-color: rgba(93,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(117,255,132,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,44,11,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,12,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,18,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,21,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,23,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,26,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,28,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,31,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,34,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,37,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,40,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,44,1)'></td>
+ <td width='1' style='background-color: rgba(2,193,47,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,238,59,1)'></td>
+ <td width='1' style='background-color: rgba(3,255,63,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,75,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,81,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,87,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,100,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,106,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,112,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,137,1)'></td>
+ <td width='1' style='background-color: rgba(108,255,143,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,38,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,28,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,32,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,35,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,39,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,43,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,47,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,52,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,56,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,61,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,66,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,83,1)'></td>
+ <td width='1' style='background-color: rgba(2,238,88,1)'></td>
+ <td width='1' style='background-color: rgba(3,255,95,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,100,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,120,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,141,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,146,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,156,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,32,15,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,29,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,38,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,42,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,47,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,52,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,58,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,63,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,69,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,76,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,82,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,208,103,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,111,1)'></td>
+ <td width='1' style='background-color: rgba(2,238,118,1)'></td>
+ <td width='1' style='background-color: rgba(3,255,127,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,139,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,143,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,147,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,160,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,164,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,172,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,26,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,20,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,23,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,27,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,37,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,42,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,47,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,53,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,59,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,66,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,72,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,80,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,87,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,193,120,1)'></td>
+ <td width='1' style='background-color: rgba(2,208,129,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,139,1)'></td>
+ <td width='1' style='background-color: rgba(2,238,148,1)'></td>
+ <td width='1' style='background-color: rgba(3,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,162,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,165,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,171,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,177,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,21,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,24,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,28,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,50,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,57,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,64,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,71,1)'></td>
+ <td width='1' style='background-color: rgba(0,106,79,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,167,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,178,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,191,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,193,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,195,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,197,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,199,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,201,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,203,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,205,1)'></td>
+ <td width='1' style='background-color: rgba(67,255,207,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,209,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,16,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,18,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,23,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,28,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,39,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,45,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,75,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,83,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,208,181,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,195,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,208,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,225,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,226,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(67,255,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(1,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(1,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(1,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,8,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,11,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,18,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,23,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,45,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,75,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,84,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,93,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,134,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,157,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,169,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,182,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,196,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,225,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(41,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(50,230,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,4,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,7,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,51,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,57,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,72,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,79,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,96,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,115,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,124,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,135,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,156,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,179,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,196,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,200,255,1)'></td>
+ <td width='1' style='background-color: rgba(41,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,2,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,20,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,23,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,37,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,42,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,60,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,66,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,73,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,80,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,104,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,121,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,130,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,149,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,160,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,169,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,172,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,1,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,34,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,43,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,58,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,70,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,83,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,90,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,97,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,104,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,119,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,132,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,25,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,36,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,57,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,62,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,72,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,78,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,84,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,89,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,96,255,1)'></td>
+ <td width='1' style='background-color: rgba(8,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(16,106,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,11,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,17,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,35,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,41,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,45,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,56,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,255,1)'></td>
+ <td width='1' style='background-color: rgba(8,70,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,7,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,17,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,20,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-filtering/f01n2c08.png b/image/test/reftest/pngsuite-filtering/f01n2c08.png
new file mode 100644
index 0000000000..26fee958ce
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f01n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-filtering/f02n0g08.html b/image/test/reftest/pngsuite-filtering/f02n0g08.html
new file mode 100644
index 0000000000..c9a6263f47
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f02n0g08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-filtering/f02n0g08.png b/image/test/reftest/pngsuite-filtering/f02n0g08.png
new file mode 100644
index 0000000000..bfe410c5e7
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f02n0g08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-filtering/f02n2c08.html b/image/test/reftest/pngsuite-filtering/f02n2c08.html
new file mode 100644
index 0000000000..051691ab99
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f02n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,8,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,16,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,24,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,32,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,41,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,49,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,57,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,65,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,82,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,90,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,106,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,148,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,29,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,31,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,38,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,45,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,52,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,59,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,67,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,81,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,88,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,96,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,103,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,110,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,117,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,124,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,132,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,153,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,161,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,175,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,55,7,1)'></td>
+ <td width='1' style='background-color: rgba(238,59,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,63,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,69,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,75,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,81,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,87,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,93,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,100,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,106,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,112,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,118,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,124,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,137,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,143,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,149,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(208,77,6,1)'></td>
+ <td width='1' style='background-color: rgba(223,83,7,1)'></td>
+ <td width='1' style='background-color: rgba(238,88,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,95,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,100,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,110,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,120,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,125,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,141,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,167,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,187,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,208,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(193,96,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,103,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,111,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,118,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,127,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,143,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,147,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,160,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,176,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,184,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,201,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(179,111,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,120,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,129,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,139,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,148,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,165,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,171,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,196,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,208,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,214,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,220,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,215,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,124,4,1)'></td>
+ <td width='1' style='background-color: rgba(179,134,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,144,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,155,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,167,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,178,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,191,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,195,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,201,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,207,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,215,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(152,133,4,1)'></td>
+ <td width='1' style='background-color: rgba(165,145,4,1)'></td>
+ <td width='1' style='background-color: rgba(179,156,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,169,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,181,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,195,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,208,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,225,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,231,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,235,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,237,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,243,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,244,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,198,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,14,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,22,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,30,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,94,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,182,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,190,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(112,128,3,1)'></td>
+ <td width='1' style='background-color: rgba(123,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(134,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(145,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(157,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(169,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(182,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(196,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(209,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(225,255,14,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,94,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(244,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,182,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(88,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(96,128,3,1)'></td>
+ <td width='1' style='background-color: rgba(105,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(115,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(124,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(135,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(145,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(156,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(168,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(179,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(200,255,38,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,46,1)'></td>
+ <td width='1' style='background-color: rgba(204,255,54,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,62,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,94,1)'></td>
+ <td width='1' style='background-color: rgba(216,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(220,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,174,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(66,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(73,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(80,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(88,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(95,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(104,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(112,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(121,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(130,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(140,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(149,238,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,29,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,37,1)'></td>
+ <td width='1' style='background-color: rgba(175,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(196,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(215,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,166,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(48,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(53,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(58,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(64,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(70,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(76,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(83,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(90,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(97,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(104,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(112,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,13,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,29,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,37,1)'></td>
+ <td width='1' style='background-color: rgba(148,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(177,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(185,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(201,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,158,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(32,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(36,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(39,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(44,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(48,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(52,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(57,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(62,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(67,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(72,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(78,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(84,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(89,238,4,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,5,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,13,1)'></td>
+ <td width='1' style='background-color: rgba(106,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,29,1)'></td>
+ <td width='1' style='background-color: rgba(116,255,37,1)'></td>
+ <td width='1' style='background-color: rgba(121,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(142,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(157,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(162,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(167,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,150,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(19,76,1,1)'></td>
+ <td width='1' style='background-color: rgba(21,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(24,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(26,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(29,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(32,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(35,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(38,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(41,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(45,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(48,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(52,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(56,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(59,238,4,1)'></td>
+ <td width='1' style='background-color: rgba(64,255,5,1)'></td>
+ <td width='1' style='background-color: rgba(70,255,13,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,29,1)'></td>
+ <td width='1' style='background-color: rgba(88,255,37,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(113,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(119,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(131,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(150,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(162,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,142,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(8,67,1,1)'></td>
+ <td width='1' style='background-color: rgba(9,76,1,1)'></td>
+ <td width='1' style='background-color: rgba(10,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(12,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(13,106,1,1)'></td>
+ <td width='1' style='background-color: rgba(14,117,1,1)'></td>
+ <td width='1' style='background-color: rgba(16,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(17,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(19,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(20,165,2,1)'></td>
+ <td width='1' style='background-color: rgba(22,179,2,1)'></td>
+ <td width='1' style='background-color: rgba(24,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(26,208,3,1)'></td>
+ <td width='1' style='background-color: rgba(28,223,3,1)'></td>
+ <td width='1' style='background-color: rgba(29,238,3,1)'></td>
+ <td width='1' style='background-color: rgba(32,255,4,1)'></td>
+ <td width='1' style='background-color: rgba(39,255,12,1)'></td>
+ <td width='1' style='background-color: rgba(46,255,20,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,52,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,60,1)'></td>
+ <td width='1' style='background-color: rgba(89,255,68,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,76,1)'></td>
+ <td width='1' style='background-color: rgba(103,255,84,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(118,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(139,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,133,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,67,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,128,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,193,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,208,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(4,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(36,255,32,1)'></td>
+ <td width='1' style='background-color: rgba(44,255,41,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,49,1)'></td>
+ <td width='1' style='background-color: rgba(60,255,57,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,65,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,82,1)'></td>
+ <td width='1' style='background-color: rgba(93,255,90,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,106,1)'></td>
+ <td width='1' style='background-color: rgba(117,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,123,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,52,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,7,1)'></td>
+ <td width='1' style='background-color: rgba(1,67,8,1)'></td>
+ <td width='1' style='background-color: rgba(1,76,9,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,10,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,11,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,12,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,14,1)'></td>
+ <td width='1' style='background-color: rgba(2,128,15,1)'></td>
+ <td width='1' style='background-color: rgba(2,140,17,1)'></td>
+ <td width='1' style='background-color: rgba(2,152,18,1)'></td>
+ <td width='1' style='background-color: rgba(2,165,20,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,21,1)'></td>
+ <td width='1' style='background-color: rgba(3,193,23,1)'></td>
+ <td width='1' style='background-color: rgba(3,208,25,1)'></td>
+ <td width='1' style='background-color: rgba(3,223,27,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(20,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(28,255,52,1)'></td>
+ <td width='1' style='background-color: rgba(36,255,59,1)'></td>
+ <td width='1' style='background-color: rgba(44,255,67,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(60,255,81,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,88,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,96,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,103,1)'></td>
+ <td width='1' style='background-color: rgba(93,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(117,255,132,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,44,11,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,12,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,18,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,21,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,23,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,26,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,28,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,31,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,34,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,37,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,40,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,44,1)'></td>
+ <td width='1' style='background-color: rgba(2,193,47,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,255,63,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,75,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,81,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,87,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,100,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,106,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,112,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,137,1)'></td>
+ <td width='1' style='background-color: rgba(108,255,143,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,38,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,28,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,32,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,35,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,39,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,43,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,47,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,52,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,56,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,61,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,83,1)'></td>
+ <td width='1' style='background-color: rgba(2,238,88,1)'></td>
+ <td width='1' style='background-color: rgba(3,255,95,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,100,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,120,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,141,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,146,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,156,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,32,15,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,29,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,38,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,42,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,47,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,52,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,58,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,63,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,69,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,193,96,1)'></td>
+ <td width='1' style='background-color: rgba(2,208,103,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,111,1)'></td>
+ <td width='1' style='background-color: rgba(2,238,118,1)'></td>
+ <td width='1' style='background-color: rgba(3,255,127,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,139,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,143,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,147,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,160,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,164,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,172,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,26,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,20,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,23,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,27,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,37,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,42,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,47,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,53,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,59,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,66,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,72,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,103,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,111,1)'></td>
+ <td width='1' style='background-color: rgba(2,193,120,1)'></td>
+ <td width='1' style='background-color: rgba(2,208,129,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,139,1)'></td>
+ <td width='1' style='background-color: rgba(2,238,148,1)'></td>
+ <td width='1' style='background-color: rgba(3,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,162,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,165,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,171,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,177,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,21,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,24,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,28,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,50,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,57,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,64,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,71,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,178,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,191,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,193,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,195,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,197,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,199,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,201,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,203,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,205,1)'></td>
+ <td width='1' style='background-color: rgba(67,255,207,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,209,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,16,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,18,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,23,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,28,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,39,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,45,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,75,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,195,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,208,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,225,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,226,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(67,255,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(1,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(1,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(1,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,8,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,11,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,18,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,23,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,45,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,75,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,84,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,93,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,134,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,157,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,169,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,182,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,196,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,225,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(41,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(50,230,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,4,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,7,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,51,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,57,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,72,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,79,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,96,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,115,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,124,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,135,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,156,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,179,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,196,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,200,255,1)'></td>
+ <td width='1' style='background-color: rgba(41,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,2,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,20,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,23,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,37,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,42,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,60,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,66,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,73,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,80,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,104,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,121,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,130,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,149,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,160,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,169,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,172,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,1,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,34,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,43,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,58,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,70,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,83,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,90,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,97,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,104,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,119,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,132,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,25,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,36,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,57,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,62,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,72,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,78,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,84,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,89,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,96,255,1)'></td>
+ <td width='1' style='background-color: rgba(8,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(16,106,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,11,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,17,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,35,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,41,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,45,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,56,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,255,1)'></td>
+ <td width='1' style='background-color: rgba(8,70,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,7,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,17,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,20,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-filtering/f02n2c08.png b/image/test/reftest/pngsuite-filtering/f02n2c08.png
new file mode 100644
index 0000000000..e590f12348
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f02n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-filtering/f03n0g08.html b/image/test/reftest/pngsuite-filtering/f03n0g08.html
new file mode 100644
index 0000000000..f40bbe51b7
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f03n0g08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-filtering/f03n0g08.png b/image/test/reftest/pngsuite-filtering/f03n0g08.png
new file mode 100644
index 0000000000..ed01e2923c
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f03n0g08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-filtering/f03n2c08.html b/image/test/reftest/pngsuite-filtering/f03n2c08.html
new file mode 100644
index 0000000000..3d3c85e6cf
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f03n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,8,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,16,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,24,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,32,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,41,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,49,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,57,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,65,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,82,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,90,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,106,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,148,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,29,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,31,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,38,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,45,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,52,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,59,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,67,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,81,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,88,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,96,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,103,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,110,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,117,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,124,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,132,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,153,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,161,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,175,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,55,7,1)'></td>
+ <td width='1' style='background-color: rgba(238,59,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,63,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,69,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,75,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,81,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,87,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,93,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,100,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,106,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,112,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,118,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,124,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,137,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,143,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,149,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(208,77,6,1)'></td>
+ <td width='1' style='background-color: rgba(223,83,7,1)'></td>
+ <td width='1' style='background-color: rgba(238,88,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,95,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,100,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,110,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,120,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,125,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,141,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,167,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,187,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,208,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(193,96,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,103,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,111,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,118,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,127,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,143,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,147,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,160,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,176,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,184,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,201,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(179,111,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,120,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,129,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,139,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,148,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,165,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,171,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,196,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,208,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,214,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,220,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,215,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,124,4,1)'></td>
+ <td width='1' style='background-color: rgba(179,134,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,144,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,155,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,167,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,178,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,191,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,195,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,201,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,207,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,215,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(152,133,4,1)'></td>
+ <td width='1' style='background-color: rgba(165,145,4,1)'></td>
+ <td width='1' style='background-color: rgba(179,156,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,169,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,181,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,195,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,208,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,225,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,231,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,235,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,237,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,243,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,244,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,198,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,14,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,182,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,190,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(112,128,3,1)'></td>
+ <td width='1' style='background-color: rgba(123,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(134,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(145,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(157,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(169,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(182,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(196,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(209,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(225,255,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(244,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,182,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(88,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(96,128,3,1)'></td>
+ <td width='1' style='background-color: rgba(105,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(115,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(124,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(135,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(145,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(156,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(168,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(179,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,14,1)'></td>
+ <td width='1' style='background-color: rgba(196,255,22,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,30,1)'></td>
+ <td width='1' style='background-color: rgba(200,255,38,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,46,1)'></td>
+ <td width='1' style='background-color: rgba(204,255,54,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,86,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,94,1)'></td>
+ <td width='1' style='background-color: rgba(216,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(220,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,174,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(66,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(73,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(80,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(88,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(95,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(104,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(112,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(121,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(130,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(140,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(149,238,4,1)'></td>
+ <td width='1' style='background-color: rgba(160,255,5,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,13,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(169,255,29,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,37,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(184,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(187,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(196,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(215,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,166,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(48,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(53,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(58,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(64,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(70,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(76,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(83,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(90,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(97,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(104,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(112,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(119,238,4,1)'></td>
+ <td width='1' style='background-color: rgba(128,255,5,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,13,1)'></td>
+ <td width='1' style='background-color: rgba(136,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(160,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(177,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(185,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(201,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,158,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(32,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(36,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(39,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(44,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(48,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(52,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(57,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(62,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(67,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(72,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(78,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(84,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(89,238,4,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,5,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(116,255,37,1)'></td>
+ <td width='1' style='background-color: rgba(121,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(126,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(131,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(142,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(157,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(162,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(167,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,150,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(19,76,1,1)'></td>
+ <td width='1' style='background-color: rgba(21,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(24,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(26,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(29,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(32,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(35,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(38,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(41,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(45,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(48,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(52,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(56,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(94,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(107,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(113,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(119,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(131,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(150,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(162,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,142,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(8,67,1,1)'></td>
+ <td width='1' style='background-color: rgba(9,76,1,1)'></td>
+ <td width='1' style='background-color: rgba(10,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(12,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(13,106,1,1)'></td>
+ <td width='1' style='background-color: rgba(14,117,1,1)'></td>
+ <td width='1' style='background-color: rgba(16,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(17,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(19,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(20,165,2,1)'></td>
+ <td width='1' style='background-color: rgba(22,179,2,1)'></td>
+ <td width='1' style='background-color: rgba(24,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(26,208,3,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(32,255,4,1)'></td>
+ <td width='1' style='background-color: rgba(39,255,12,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(67,255,44,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,52,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,60,1)'></td>
+ <td width='1' style='background-color: rgba(89,255,68,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,76,1)'></td>
+ <td width='1' style='background-color: rgba(103,255,84,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(118,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(139,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,133,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,67,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,128,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,193,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,208,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(4,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(12,255,8,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(44,255,41,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,49,1)'></td>
+ <td width='1' style='background-color: rgba(60,255,57,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,65,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,82,1)'></td>
+ <td width='1' style='background-color: rgba(93,255,90,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,106,1)'></td>
+ <td width='1' style='background-color: rgba(117,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,123,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,52,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,7,1)'></td>
+ <td width='1' style='background-color: rgba(1,67,8,1)'></td>
+ <td width='1' style='background-color: rgba(1,76,9,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,10,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,11,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,12,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,14,1)'></td>
+ <td width='1' style='background-color: rgba(2,128,15,1)'></td>
+ <td width='1' style='background-color: rgba(2,140,17,1)'></td>
+ <td width='1' style='background-color: rgba(2,152,18,1)'></td>
+ <td width='1' style='background-color: rgba(2,165,20,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,21,1)'></td>
+ <td width='1' style='background-color: rgba(3,193,23,1)'></td>
+ <td width='1' style='background-color: rgba(3,208,25,1)'></td>
+ <td width='1' style='background-color: rgba(3,223,27,1)'></td>
+ <td width='1' style='background-color: rgba(3,238,29,1)'></td>
+ <td width='1' style='background-color: rgba(4,255,31,1)'></td>
+ <td width='1' style='background-color: rgba(12,255,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(36,255,59,1)'></td>
+ <td width='1' style='background-color: rgba(44,255,67,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(60,255,81,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,88,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,96,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,103,1)'></td>
+ <td width='1' style='background-color: rgba(93,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(117,255,132,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,44,11,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,12,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,18,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,21,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,23,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,26,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,28,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,31,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,34,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,37,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,40,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,44,1)'></td>
+ <td width='1' style='background-color: rgba(2,193,47,1)'></td>
+ <td width='1' style='background-color: rgba(2,208,51,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,55,1)'></td>
+ <td width='1' style='background-color: rgba(2,238,59,1)'></td>
+ <td width='1' style='background-color: rgba(3,255,63,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,81,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,87,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,100,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,106,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,112,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,137,1)'></td>
+ <td width='1' style='background-color: rgba(108,255,143,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,38,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,28,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,32,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,35,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,39,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,43,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,47,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,52,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,56,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,61,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,66,1)'></td>
+ <td width='1' style='background-color: rgba(2,193,72,1)'></td>
+ <td width='1' style='background-color: rgba(2,208,77,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,83,1)'></td>
+ <td width='1' style='background-color: rgba(2,238,88,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,120,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,141,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,146,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,156,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,32,15,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,29,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,38,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,42,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,47,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,52,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,58,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,76,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,82,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,89,1)'></td>
+ <td width='1' style='background-color: rgba(2,193,96,1)'></td>
+ <td width='1' style='background-color: rgba(2,208,103,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,139,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,143,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,147,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,160,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,164,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,172,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,26,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,20,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,23,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,27,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,37,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,42,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,47,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,53,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,59,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,66,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,95,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,103,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,111,1)'></td>
+ <td width='1' style='background-color: rgba(2,193,120,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,162,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,165,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,171,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,177,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,21,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,24,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,28,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,50,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,57,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,64,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,71,1)'></td>
+ <td width='1' style='background-color: rgba(0,106,79,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,167,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,178,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,191,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,193,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,195,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,197,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,199,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,201,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,203,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,205,1)'></td>
+ <td width='1' style='background-color: rgba(67,255,207,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,209,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,16,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,18,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,23,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,28,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,39,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,45,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,75,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,83,1)'></td>
+ <td width='1' style='background-color: rgba(0,106,92,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,193,169,1)'></td>
+ <td width='1' style='background-color: rgba(1,208,181,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,195,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,208,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,225,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,226,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(67,255,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(1,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(1,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(1,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,8,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,11,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,18,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,23,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,45,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,75,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,84,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,93,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,134,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,157,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,169,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,182,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,196,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,225,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(41,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(50,230,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,4,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,7,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,51,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,57,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,72,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,79,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,96,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,115,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,124,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,135,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,156,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,179,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,196,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,200,255,1)'></td>
+ <td width='1' style='background-color: rgba(41,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,2,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,20,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,23,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,37,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,42,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,60,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,66,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,73,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,80,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,104,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,121,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,130,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,149,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,160,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,169,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,172,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,1,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,34,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,43,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,58,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,70,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,83,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,90,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,97,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,104,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,119,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,132,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,25,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,36,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,57,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,62,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,72,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,78,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,84,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,89,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,96,255,1)'></td>
+ <td width='1' style='background-color: rgba(8,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(16,106,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,11,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,17,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,35,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,41,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,45,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,56,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,255,1)'></td>
+ <td width='1' style='background-color: rgba(8,70,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,7,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,17,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,20,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-filtering/f03n2c08.png b/image/test/reftest/pngsuite-filtering/f03n2c08.png
new file mode 100644
index 0000000000..758115059d
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f03n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-filtering/f04n0g08.html b/image/test/reftest/pngsuite-filtering/f04n0g08.html
new file mode 100644
index 0000000000..3c7ce550ba
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f04n0g08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,1,1,1)'></td>
+ <td width='1' style='background-color: rgba(2,2,2,1)'></td>
+ <td width='1' style='background-color: rgba(3,3,3,1)'></td>
+ <td width='1' style='background-color: rgba(4,4,4,1)'></td>
+ <td width='1' style='background-color: rgba(6,6,6,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(10,10,10,1)'></td>
+ <td width='1' style='background-color: rgba(13,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(15,15,15,1)'></td>
+ <td width='1' style='background-color: rgba(19,19,19,1)'></td>
+ <td width='1' style='background-color: rgba(22,22,22,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(29,29,29,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(38,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(42,42,42,1)'></td>
+ <td width='1' style='background-color: rgba(47,47,47,1)'></td>
+ <td width='1' style='background-color: rgba(52,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(63,63,63,1)'></td>
+ <td width='1' style='background-color: rgba(69,69,69,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-filtering/f04n0g08.png b/image/test/reftest/pngsuite-filtering/f04n0g08.png
new file mode 100644
index 0000000000..663fdae3e7
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f04n0g08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-filtering/f04n2c08.html b/image/test/reftest/pngsuite-filtering/f04n2c08.html
new file mode 100644
index 0000000000..77c90face2
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f04n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,8,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,16,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,24,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,32,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,41,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,49,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,57,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,65,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,82,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,90,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,98,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,106,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,123,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,148,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,222,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,247,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,29,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,31,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,38,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,45,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,52,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,59,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,67,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,74,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,81,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,88,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,96,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,103,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,110,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,117,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,124,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,132,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,153,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,161,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,175,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,204,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,239,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,55,7,1)'></td>
+ <td width='1' style='background-color: rgba(238,59,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,63,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,69,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,75,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,81,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,87,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,93,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,100,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,106,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,112,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,118,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,124,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,137,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,143,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,149,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,231,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(208,77,6,1)'></td>
+ <td width='1' style='background-color: rgba(223,83,7,1)'></td>
+ <td width='1' style='background-color: rgba(238,88,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,95,8,1)'></td>
+ <td width='1' style='background-color: rgba(255,100,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,105,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,110,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,115,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,120,47,1)'></td>
+ <td width='1' style='background-color: rgba(255,125,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,136,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,141,79,1)'></td>
+ <td width='1' style='background-color: rgba(255,146,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,156,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,111,1)'></td>
+ <td width='1' style='background-color: rgba(255,167,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,182,143,1)'></td>
+ <td width='1' style='background-color: rgba(255,187,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,198,167,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,175,1)'></td>
+ <td width='1' style='background-color: rgba(255,208,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,218,199,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,207,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,223,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(193,96,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,103,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,111,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,118,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,127,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,131,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,135,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,139,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,143,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,147,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,151,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,160,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,164,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,172,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,176,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,184,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,188,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,201,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,215,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(179,111,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,120,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,129,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,139,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,148,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,159,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,162,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,165,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,168,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,171,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,174,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,177,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,183,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,186,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,189,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,196,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,202,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,208,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,214,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,220,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,206,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,215,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,124,4,1)'></td>
+ <td width='1' style='background-color: rgba(179,134,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,144,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,155,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,167,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,178,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,191,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,193,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,195,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,197,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,199,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,201,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,203,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,205,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,207,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,209,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,213,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,215,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,217,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,219,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,221,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,198,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(152,133,4,1)'></td>
+ <td width='1' style='background-color: rgba(165,145,4,1)'></td>
+ <td width='1' style='background-color: rgba(179,156,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,169,5,1)'></td>
+ <td width='1' style='background-color: rgba(208,181,5,1)'></td>
+ <td width='1' style='background-color: rgba(223,195,6,1)'></td>
+ <td width='1' style='background-color: rgba(238,208,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,223,7,1)'></td>
+ <td width='1' style='background-color: rgba(255,224,15,1)'></td>
+ <td width='1' style='background-color: rgba(255,225,23,1)'></td>
+ <td width='1' style='background-color: rgba(255,226,31,1)'></td>
+ <td width='1' style='background-color: rgba(255,227,39,1)'></td>
+ <td width='1' style='background-color: rgba(255,228,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,229,55,1)'></td>
+ <td width='1' style='background-color: rgba(255,230,63,1)'></td>
+ <td width='1' style='background-color: rgba(255,231,71,1)'></td>
+ <td width='1' style='background-color: rgba(255,232,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,233,87,1)'></td>
+ <td width='1' style='background-color: rgba(255,234,95,1)'></td>
+ <td width='1' style='background-color: rgba(255,235,103,1)'></td>
+ <td width='1' style='background-color: rgba(255,236,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,237,119,1)'></td>
+ <td width='1' style='background-color: rgba(255,238,127,1)'></td>
+ <td width='1' style='background-color: rgba(255,239,135,1)'></td>
+ <td width='1' style='background-color: rgba(255,240,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,241,151,1)'></td>
+ <td width='1' style='background-color: rgba(255,242,159,1)'></td>
+ <td width='1' style='background-color: rgba(255,243,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,244,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,245,183,1)'></td>
+ <td width='1' style='background-color: rgba(255,246,191,1)'></td>
+ <td width='1' style='background-color: rgba(255,247,198,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(140,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,14,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,22,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,30,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,38,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,46,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,54,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,78,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,86,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,94,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,182,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,190,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(112,128,3,1)'></td>
+ <td width='1' style='background-color: rgba(123,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(134,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(145,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(157,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(169,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(182,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(196,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(209,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(225,255,14,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,22,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,30,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,38,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,46,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,70,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,78,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,86,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,94,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(236,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(238,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(240,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(242,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(244,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(246,255,182,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(88,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(96,128,3,1)'></td>
+ <td width='1' style='background-color: rgba(105,140,3,1)'></td>
+ <td width='1' style='background-color: rgba(115,152,3,1)'></td>
+ <td width='1' style='background-color: rgba(124,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(135,179,4,1)'></td>
+ <td width='1' style='background-color: rgba(145,193,4,1)'></td>
+ <td width='1' style='background-color: rgba(156,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(168,223,5,1)'></td>
+ <td width='1' style='background-color: rgba(179,238,5,1)'></td>
+ <td width='1' style='background-color: rgba(192,255,6,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,14,1)'></td>
+ <td width='1' style='background-color: rgba(196,255,22,1)'></td>
+ <td width='1' style='background-color: rgba(198,255,30,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,62,1)'></td>
+ <td width='1' style='background-color: rgba(208,255,70,1)'></td>
+ <td width='1' style='background-color: rgba(210,255,78,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,86,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,94,1)'></td>
+ <td width='1' style='background-color: rgba(216,255,102,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(220,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,126,1)'></td>
+ <td width='1' style='background-color: rgba(224,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(226,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(228,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(232,255,166,1)'></td>
+ <td width='1' style='background-color: rgba(234,255,174,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(66,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(73,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(80,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(88,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(95,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(104,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(112,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(121,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(130,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(140,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(149,238,4,1)'></td>
+ <td width='1' style='background-color: rgba(160,255,5,1)'></td>
+ <td width='1' style='background-color: rgba(163,255,13,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(175,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(184,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(187,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(190,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(196,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(202,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(212,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(215,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,158,1)'></td>
+ <td width='1' style='background-color: rgba(221,255,166,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(48,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(53,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(58,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(64,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(70,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(76,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(83,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(90,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(97,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(104,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(112,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(119,238,4,1)'></td>
+ <td width='1' style='background-color: rgba(128,255,5,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,37,1)'></td>
+ <td width='1' style='background-color: rgba(148,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(160,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(164,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(177,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(185,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(193,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(201,255,150,1)'></td>
+ <td width='1' style='background-color: rgba(205,255,158,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(32,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(36,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(39,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(44,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(48,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(52,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(57,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(62,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(67,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(72,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(78,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(84,223,4,1)'></td>
+ <td width='1' style='background-color: rgba(89,238,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(106,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,29,1)'></td>
+ <td width='1' style='background-color: rgba(116,255,37,1)'></td>
+ <td width='1' style='background-color: rgba(121,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(126,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(131,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(142,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(157,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(162,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(167,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,142,1)'></td>
+ <td width='1' style='background-color: rgba(188,255,150,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(19,76,1,1)'></td>
+ <td width='1' style='background-color: rgba(21,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(24,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(26,106,2,1)'></td>
+ <td width='1' style='background-color: rgba(29,117,2,1)'></td>
+ <td width='1' style='background-color: rgba(32,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(35,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(38,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(41,165,3,1)'></td>
+ <td width='1' style='background-color: rgba(45,179,3,1)'></td>
+ <td width='1' style='background-color: rgba(48,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(52,208,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(70,255,13,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,21,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,29,1)'></td>
+ <td width='1' style='background-color: rgba(88,255,37,1)'></td>
+ <td width='1' style='background-color: rgba(94,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,53,1)'></td>
+ <td width='1' style='background-color: rgba(107,255,61,1)'></td>
+ <td width='1' style='background-color: rgba(113,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(119,255,77,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,85,1)'></td>
+ <td width='1' style='background-color: rgba(131,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(137,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(144,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(150,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(162,255,134,1)'></td>
+ <td width='1' style='background-color: rgba(168,255,142,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(8,67,1,1)'></td>
+ <td width='1' style='background-color: rgba(9,76,1,1)'></td>
+ <td width='1' style='background-color: rgba(10,85,1,1)'></td>
+ <td width='1' style='background-color: rgba(12,95,1,1)'></td>
+ <td width='1' style='background-color: rgba(13,106,1,1)'></td>
+ <td width='1' style='background-color: rgba(14,117,1,1)'></td>
+ <td width='1' style='background-color: rgba(16,128,2,1)'></td>
+ <td width='1' style='background-color: rgba(17,140,2,1)'></td>
+ <td width='1' style='background-color: rgba(19,152,2,1)'></td>
+ <td width='1' style='background-color: rgba(20,165,2,1)'></td>
+ <td width='1' style='background-color: rgba(22,179,2,1)'></td>
+ <td width='1' style='background-color: rgba(24,193,3,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(29,238,3,1)'></td>
+ <td width='1' style='background-color: rgba(32,255,4,1)'></td>
+ <td width='1' style='background-color: rgba(39,255,12,1)'></td>
+ <td width='1' style='background-color: rgba(46,255,20,1)'></td>
+ <td width='1' style='background-color: rgba(53,255,28,1)'></td>
+ <td width='1' style='background-color: rgba(60,255,36,1)'></td>
+ <td width='1' style='background-color: rgba(67,255,44,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,52,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,60,1)'></td>
+ <td width='1' style='background-color: rgba(89,255,68,1)'></td>
+ <td width='1' style='background-color: rgba(96,255,76,1)'></td>
+ <td width='1' style='background-color: rgba(103,255,84,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(118,255,101,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,109,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(139,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(147,255,133,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,59,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,67,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,76,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,128,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,238,0,1)'></td>
+ <td width='1' style='background-color: rgba(4,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(28,255,24,1)'></td>
+ <td width='1' style='background-color: rgba(36,255,32,1)'></td>
+ <td width='1' style='background-color: rgba(44,255,41,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,49,1)'></td>
+ <td width='1' style='background-color: rgba(60,255,57,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,65,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,82,1)'></td>
+ <td width='1' style='background-color: rgba(93,255,90,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,98,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,106,1)'></td>
+ <td width='1' style='background-color: rgba(117,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(125,255,123,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,52,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,7,1)'></td>
+ <td width='1' style='background-color: rgba(1,67,8,1)'></td>
+ <td width='1' style='background-color: rgba(1,76,9,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,10,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,11,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,12,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,14,1)'></td>
+ <td width='1' style='background-color: rgba(2,128,15,1)'></td>
+ <td width='1' style='background-color: rgba(2,140,17,1)'></td>
+ <td width='1' style='background-color: rgba(2,152,18,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(3,193,23,1)'></td>
+ <td width='1' style='background-color: rgba(3,208,25,1)'></td>
+ <td width='1' style='background-color: rgba(3,223,27,1)'></td>
+ <td width='1' style='background-color: rgba(3,238,29,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(20,255,45,1)'></td>
+ <td width='1' style='background-color: rgba(28,255,52,1)'></td>
+ <td width='1' style='background-color: rgba(36,255,59,1)'></td>
+ <td width='1' style='background-color: rgba(44,255,67,1)'></td>
+ <td width='1' style='background-color: rgba(52,255,74,1)'></td>
+ <td width='1' style='background-color: rgba(60,255,81,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,88,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,96,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,103,1)'></td>
+ <td width='1' style='background-color: rgba(93,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(101,255,117,1)'></td>
+ <td width='1' style='background-color: rgba(109,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(117,255,132,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,44,11,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,12,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,18,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,21,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,23,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,26,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,28,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,31,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,34,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,44,1)'></td>
+ <td width='1' style='background-color: rgba(2,193,47,1)'></td>
+ <td width='1' style='background-color: rgba(2,208,51,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,55,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,69,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,75,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,81,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,87,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,93,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,100,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,106,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,112,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,118,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,124,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,137,1)'></td>
+ <td width='1' style='background-color: rgba(108,255,143,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,38,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,28,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,32,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,35,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,39,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,43,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,47,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,105,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,110,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,115,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,120,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,125,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,136,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,141,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,146,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,156,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,32,15,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,22,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,29,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,38,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,42,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,47,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,52,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,58,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,131,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,135,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,139,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,143,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,147,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,151,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,155,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,160,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,164,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(92,255,172,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,26,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,20,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,23,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,27,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,37,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,42,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,47,1)'></td>
+ <td width='1' style='background-color: rgba(1,85,53,1)'></td>
+ <td width='1' style='background-color: rgba(1,95,59,1)'></td>
+ <td width='1' style='background-color: rgba(1,106,66,1)'></td>
+ <td width='1' style='background-color: rgba(1,117,72,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,80,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,87,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,95,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,103,1)'></td>
+ <td width='1' style='background-color: rgba(2,179,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(2,223,139,1)'></td>
+ <td width='1' style='background-color: rgba(2,238,148,1)'></td>
+ <td width='1' style='background-color: rgba(3,255,159,1)'></td>
+ <td width='1' style='background-color: rgba(11,255,162,1)'></td>
+ <td width='1' style='background-color: rgba(19,255,165,1)'></td>
+ <td width='1' style='background-color: rgba(27,255,168,1)'></td>
+ <td width='1' style='background-color: rgba(35,255,171,1)'></td>
+ <td width='1' style='background-color: rgba(43,255,174,1)'></td>
+ <td width='1' style='background-color: rgba(51,255,177,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(68,255,183,1)'></td>
+ <td width='1' style='background-color: rgba(76,255,186,1)'></td>
+ <td width='1' style='background-color: rgba(84,255,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,21,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,19,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,24,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,28,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,50,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,57,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,64,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,71,1)'></td>
+ <td width='1' style='background-color: rgba(0,106,79,1)'></td>
+ <td width='1' style='background-color: rgba(0,117,87,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,96,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,105,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,114,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,124,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,208,155,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,167,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,178,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,191,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,193,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,195,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,197,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,199,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,201,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,203,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,205,1)'></td>
+ <td width='1' style='background-color: rgba(67,255,207,1)'></td>
+ <td width='1' style='background-color: rgba(75,255,209,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,16,14,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,18,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,23,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,28,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,39,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,45,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,75,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,83,1)'></td>
+ <td width='1' style='background-color: rgba(0,106,92,1)'></td>
+ <td width='1' style='background-color: rgba(0,117,102,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,112,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,122,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,133,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(1,193,169,1)'></td>
+ <td width='1' style='background-color: rgba(1,208,181,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,195,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,208,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,223,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,224,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,225,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,226,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,227,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,228,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,229,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,230,1)'></td>
+ <td width='1' style='background-color: rgba(67,255,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,13,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(1,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(1,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(1,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(1,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(1,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(1,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(1,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(1,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(2,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(10,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(18,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(26,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(34,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(42,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(50,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(59,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,8,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,11,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,18,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,23,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,45,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,75,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,84,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,93,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,102,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,134,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,157,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,169,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,182,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,196,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,224,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,225,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,226,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(41,228,255,1)'></td>
+ <td width='1' style='background-color: rgba(50,230,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,4,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,7,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,51,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,57,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,72,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,79,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,96,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,105,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,115,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,124,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,135,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,156,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,168,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,179,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,192,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,196,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,200,255,1)'></td>
+ <td width='1' style='background-color: rgba(41,202,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,2,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,20,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,23,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,37,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,42,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,60,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,66,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,73,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,80,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,95,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,104,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,121,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,130,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,149,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,160,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,163,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,169,255,1)'></td>
+ <td width='1' style='background-color: rgba(33,172,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,1,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,34,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,43,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,58,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,70,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,76,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,83,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,90,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,97,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,104,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,112,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,119,238,1)'></td>
+ <td width='1' style='background-color: rgba(1,128,255,1)'></td>
+ <td width='1' style='background-color: rgba(9,132,255,1)'></td>
+ <td width='1' style='background-color: rgba(17,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(25,140,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,25,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,36,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,39,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,44,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,57,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,62,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,67,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,72,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,78,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,84,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,89,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,96,255,1)'></td>
+ <td width='1' style='background-color: rgba(8,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(16,106,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,11,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,17,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,21,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,35,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,38,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,41,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,45,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,48,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,52,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,56,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,59,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,64,255,1)'></td>
+ <td width='1' style='background-color: rgba(8,70,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,1,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,2,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,4,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,6,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,9,1)'></td>
+ <td width='1' style='background-color: rgba(0,1,13,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,2,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,3,26,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,32,1)'></td>
+ <td width='1' style='background-color: rgba(0,4,38,1)'></td>
+ <td width='1' style='background-color: rgba(0,5,44,1)'></td>
+ <td width='1' style='background-color: rgba(0,6,52,1)'></td>
+ <td width='1' style='background-color: rgba(0,7,59,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,67,1)'></td>
+ <td width='1' style='background-color: rgba(0,9,76,1)'></td>
+ <td width='1' style='background-color: rgba(0,10,85,1)'></td>
+ <td width='1' style='background-color: rgba(0,12,95,1)'></td>
+ <td width='1' style='background-color: rgba(0,13,106,1)'></td>
+ <td width='1' style='background-color: rgba(0,14,117,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,128,1)'></td>
+ <td width='1' style='background-color: rgba(0,17,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,19,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,20,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,22,179,1)'></td>
+ <td width='1' style='background-color: rgba(0,24,193,1)'></td>
+ <td width='1' style='background-color: rgba(0,26,208,1)'></td>
+ <td width='1' style='background-color: rgba(0,28,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,29,238,1)'></td>
+ <td width='1' style='background-color: rgba(0,32,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-filtering/f04n2c08.png b/image/test/reftest/pngsuite-filtering/f04n2c08.png
new file mode 100644
index 0000000000..3c8b5116e7
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/f04n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-filtering/reftest.list b/image/test/reftest/pngsuite-filtering/reftest.list
new file mode 100644
index 0000000000..3a39efbbe3
--- /dev/null
+++ b/image/test/reftest/pngsuite-filtering/reftest.list
@@ -0,0 +1,22 @@
+# PngSuite - Image filtering
+
+# f00n0g08 - grayscale, no interlacing, filter-type 0
+skip-if(ThreadSanitizer) == f00n0g08.png f00n0g08.html
+# f00n2c08 - color, no interlacing, filter-type 0
+== f00n2c08.png f00n2c08.html
+# f01n0g08 - grayscale, no interlacing, filter-type 1
+== f01n0g08.png f01n0g08.html
+# f01n2c08 - color, no interlacing, filter-type 1
+== f01n2c08.png f01n2c08.html
+# f02n0g08 - grayscale, no interlacing, filter-type 2
+== f02n0g08.png f02n0g08.html
+# f02n2c08 - color, no interlacing, filter-type 2
+== f02n2c08.png f02n2c08.html
+# f03n0g08 - grayscale, no interlacing, filter-type 3
+== f03n0g08.png f03n0g08.html
+# f03n2c08 - color, no interlacing, filter-type 3
+== f03n2c08.png f03n2c08.html
+# f04n0g08 - grayscale, no interlacing, filter-type 4
+== f04n0g08.png f04n0g08.html
+# f04n2c08 - color, no interlacing, filter-type 4
+== f04n2c08.png f04n2c08.html
diff --git a/image/test/reftest/pngsuite-gamma/g03n0g16.html b/image/test/reftest/pngsuite-gamma/g03n0g16.html
new file mode 100644
index 0000000000..dc15a536b5
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g03n0g16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g03n0g16.png b/image/test/reftest/pngsuite-gamma/g03n0g16.png
new file mode 100644
index 0000000000..41083ca80f
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g03n0g16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g03n2c08.html b/image/test/reftest/pngsuite-gamma/g03n2c08.html
new file mode 100644
index 0000000000..c2d02beed9
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g03n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(234,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(234,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(234,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(234,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(234,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(234,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(234,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(234,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(198,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(193,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(193,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(193,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(193,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(193,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(193,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(193,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(193,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,255,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,255,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,255,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,255,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,255,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,255,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,255,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(182,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(182,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(182,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(182,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(182,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(182,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(182,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(182,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,255,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,255,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,255,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,255,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,255,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,255,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,255,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,255,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,255,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g03n2c08.png b/image/test/reftest/pngsuite-gamma/g03n2c08.png
new file mode 100644
index 0000000000..a9354dbee6
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g03n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g03n3p04.html b/image/test/reftest/pngsuite-gamma/g03n3p04.html
new file mode 100644
index 0000000000..efcf39f291
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g03n3p04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g03n3p04.png b/image/test/reftest/pngsuite-gamma/g03n3p04.png
new file mode 100644
index 0000000000..60396c95af
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g03n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g04n0g16.html b/image/test/reftest/pngsuite-gamma/g04n0g16.html
new file mode 100644
index 0000000000..5bec9867fa
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g04n0g16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g04n0g16.png b/image/test/reftest/pngsuite-gamma/g04n0g16.png
new file mode 100644
index 0000000000..32395b76c9
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g04n0g16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g04n2c08.html b/image/test/reftest/pngsuite-gamma/g04n2c08.html
new file mode 100644
index 0000000000..b3b0556c6e
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g04n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,255,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,255,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,255,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,255,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,255,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,255,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,255,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,255,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,255,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,255,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,255,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,255,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,255,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,255,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,255,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,255,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,255,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,255,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,255,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,255,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,255,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,255,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,255,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,255,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,255,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,255,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,255,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,255,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,255,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,255,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,255,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,255,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,255,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,255,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,255,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,255,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,255,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,255,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,255,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,255,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,255,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,255,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(166,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(153,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(153,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(146,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(146,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(146,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(146,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(146,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(146,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(146,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(146,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(130,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(112,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(112,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(101,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(101,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(89,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(89,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(89,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(89,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(89,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(89,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(89,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(89,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(54,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(54,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(54,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(54,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(54,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(54,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(54,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(54,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g04n2c08.png b/image/test/reftest/pngsuite-gamma/g04n2c08.png
new file mode 100644
index 0000000000..a652b0ce87
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g04n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g04n3p04.html b/image/test/reftest/pngsuite-gamma/g04n3p04.html
new file mode 100644
index 0000000000..337dcb49d7
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g04n3p04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g04n3p04.png b/image/test/reftest/pngsuite-gamma/g04n3p04.png
new file mode 100644
index 0000000000..5661cc3131
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g04n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g05n0g16.html b/image/test/reftest/pngsuite-gamma/g05n0g16.html
new file mode 100644
index 0000000000..ab100e638b
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g05n0g16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(54,54,54,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g05n0g16.png b/image/test/reftest/pngsuite-gamma/g05n0g16.png
new file mode 100644
index 0000000000..70b37f01e2
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g05n0g16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g05n2c08.html b/image/test/reftest/pngsuite-gamma/g05n2c08.html
new file mode 100644
index 0000000000..475ecd21df
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g05n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g05n2c08.png b/image/test/reftest/pngsuite-gamma/g05n2c08.png
new file mode 100644
index 0000000000..932c136536
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g05n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g05n3p04.html b/image/test/reftest/pngsuite-gamma/g05n3p04.html
new file mode 100644
index 0000000000..d71689c29a
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g05n3p04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g05n3p04.png b/image/test/reftest/pngsuite-gamma/g05n3p04.png
new file mode 100644
index 0000000000..9619930585
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g05n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g07n0g16.html b/image/test/reftest/pngsuite-gamma/g07n0g16.html
new file mode 100644
index 0000000000..b9f1a1c3ea
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g07n0g16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g07n0g16.png b/image/test/reftest/pngsuite-gamma/g07n0g16.png
new file mode 100644
index 0000000000..d6a47c2d57
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g07n0g16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g07n2c08.html b/image/test/reftest/pngsuite-gamma/g07n2c08.html
new file mode 100644
index 0000000000..0a5b63bf01
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g07n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g07n2c08.png b/image/test/reftest/pngsuite-gamma/g07n2c08.png
new file mode 100644
index 0000000000..597346460f
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g07n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g07n3p04.html b/image/test/reftest/pngsuite-gamma/g07n3p04.html
new file mode 100644
index 0000000000..7303ed0d70
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g07n3p04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,211,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g07n3p04.png b/image/test/reftest/pngsuite-gamma/g07n3p04.png
new file mode 100644
index 0000000000..c73fb61365
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g07n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g10n0g16.html b/image/test/reftest/pngsuite-gamma/g10n0g16.html
new file mode 100644
index 0000000000..29301dd710
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g10n0g16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g10n0g16.png b/image/test/reftest/pngsuite-gamma/g10n0g16.png
new file mode 100644
index 0000000000..85f2c958e9
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g10n0g16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g10n2c08.html b/image/test/reftest/pngsuite-gamma/g10n2c08.html
new file mode 100644
index 0000000000..24e8637b74
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g10n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,255,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,255,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,255,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,255,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,255,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,255,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,255,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(171,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(137,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,255,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,255,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,255,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,255,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,255,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(99,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(87,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(72,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(72,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(72,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(72,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(72,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(72,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(72,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(72,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g10n2c08.png b/image/test/reftest/pngsuite-gamma/g10n2c08.png
new file mode 100644
index 0000000000..b3039970c1
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g10n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g10n3p04.html b/image/test/reftest/pngsuite-gamma/g10n3p04.html
new file mode 100644
index 0000000000..7c25d439d8
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g10n3p04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,155,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g10n3p04.png b/image/test/reftest/pngsuite-gamma/g10n3p04.png
new file mode 100644
index 0000000000..1b6a6be2ca
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g10n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g25n0g16.html b/image/test/reftest/pngsuite-gamma/g25n0g16.html
new file mode 100644
index 0000000000..7f3d84edf4
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g25n0g16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(113,113,113,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g25n0g16.png b/image/test/reftest/pngsuite-gamma/g25n0g16.png
new file mode 100644
index 0000000000..a9f6787c7a
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g25n0g16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g25n2c08.html b/image/test/reftest/pngsuite-gamma/g25n2c08.html
new file mode 100644
index 0000000000..2476d2cc9d
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g25n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,255,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,255,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,255,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,255,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,255,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,255,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,255,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,255,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,255,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,255,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,255,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,255,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,255,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,255,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(177,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(144,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(144,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(136,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(136,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(129,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(120,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(106,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(106,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(106,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(106,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(106,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(106,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(106,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(106,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(93,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(93,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(93,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(93,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(93,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(93,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(93,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(93,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g25n2c08.png b/image/test/reftest/pngsuite-gamma/g25n2c08.png
new file mode 100644
index 0000000000..03f505a64b
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g25n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/g25n3p04.html b/image/test/reftest/pngsuite-gamma/g25n3p04.html
new file mode 100644
index 0000000000..3cb0205bed
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g25n3p04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,154,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,212,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-gamma/g25n3p04.png b/image/test/reftest/pngsuite-gamma/g25n3p04.png
new file mode 100644
index 0000000000..4f943c6175
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/g25n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-gamma/reftest.list b/image/test/reftest/pngsuite-gamma/reftest.list
new file mode 100644
index 0000000000..1b5abdda75
--- /dev/null
+++ b/image/test/reftest/pngsuite-gamma/reftest.list
@@ -0,0 +1,38 @@
+# PngSuite - Gamma values
+
+# g03n0g16 - grayscale, file-gamma = 0.35
+== g03n0g16.png g03n0g16.html
+# g03n2c08 - color, file-gamma = 0.35
+== g03n2c08.png g03n2c08.html
+# g03n3p04 - paletted, file-gamma = 0.35
+== g03n3p04.png g03n3p04.html
+# g04n0g16 - grayscale, file-gamma = 0.45
+== g04n0g16.png g04n0g16.html
+# g04n2c08 - color, file-gamma = 0.45
+== g04n2c08.png g04n2c08.html
+# g04n3p04 - paletted, file-gamma = 0.45
+== g04n3p04.png g04n3p04.html
+# g05n0g16 - grayscale, file-gamma = 0.55
+== g05n0g16.png g05n0g16.html
+# g05n2c08 - color, file-gamma = 0.55
+== g05n2c08.png g05n2c08.html
+# g05n3p04 - paletted, file-gamma = 0.55
+== g05n3p04.png g05n3p04.html
+# g07n0g16 - grayscale, file-gamma = 0.70
+== g07n0g16.png g07n0g16.html
+# g07n2c08 - color, file-gamma = 0.70
+== g07n2c08.png g07n2c08.html
+# g07n3p04 - paletted, file-gamma = 0.70
+== g07n3p04.png g07n3p04.html
+# g10n0g16 - grayscale, file-gamma = 1.00
+== g10n0g16.png g10n0g16.html
+# g10n2c08 - color, file-gamma = 1.00
+== g10n2c08.png g10n2c08.html
+# g10n3p04 - paletted, file-gamma = 1.00
+== g10n3p04.png g10n3p04.html
+# g25n0g16 - grayscale, file-gamma = 2.50
+== g25n0g16.png g25n0g16.html
+# g25n2c08 - color, file-gamma = 2.50
+== g25n2c08.png g25n2c08.html
+# g25n3p04 - paletted, file-gamma = 2.50
+== g25n3p04.png g25n3p04.html
diff --git a/image/test/reftest/pngsuite-oddsizes/reftest.list b/image/test/reftest/pngsuite-oddsizes/reftest.list
new file mode 100644
index 0000000000..fa72e005b6
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/reftest.list
@@ -0,0 +1,77 @@
+# PngSuite - Odd sizes
+#
+# Note: For each size, there are 2 PNGs (one interlaced, one not). Both
+# versions look identical, so they share a common HTML reference file.
+
+# s01i3p01 - 1x1 paletted file, interlaced
+== s01i3p01.png s01_3p01.html
+# s01n3p01 - 1x1 paletted file, no interlacing
+== s01n3p01.png s01_3p01.html
+# s02i3p01 - 2x2 paletted file, interlaced
+== s02i3p01.png s02_3p01.html
+# s02n3p01 - 2x2 paletted file, no interlacing
+== s02n3p01.png s02_3p01.html
+# s03i3p01 - 3x3 paletted file, interlaced
+== s03i3p01.png s03_3p01.html
+# s03n3p01 - 3x3 paletted file, no interlacing
+== s03n3p01.png s03_3p01.html
+# s04i3p01 - 4x4 paletted file, interlaced
+== s04i3p01.png s04_3p01.html
+# s04n3p01 - 4x4 paletted file, no interlacing
+== s04n3p01.png s04_3p01.html
+# s05i3p02 - 5x5 paletted file, interlaced
+== s05i3p02.png s05_3p02.html
+# s05n3p02 - 5x5 paletted file, no interlacing
+== s05n3p02.png s05_3p02.html
+# s06i3p02 - 6x6 paletted file, interlaced
+== s06i3p02.png s06_3p02.html
+# s06n3p02 - 6x6 paletted file, no interlacing
+== s06n3p02.png s06_3p02.html
+# s07i3p02 - 7x7 paletted file, interlaced
+== s07i3p02.png s07_3p02.html
+# s07n3p02 - 7x7 paletted file, no interlacing
+== s07n3p02.png s07_3p02.html
+# s08i3p02 - 8x8 paletted file, interlaced
+== s08i3p02.png s08_3p02.html
+# s08n3p02 - 8x8 paletted file, no interlacing
+== s08n3p02.png s08_3p02.html
+# s09i3p02 - 9x9 paletted file, interlaced
+== s09i3p02.png s09_3p02.html
+# s09n3p02 - 9x9 paletted file, no interlacing
+== s09n3p02.png s09_3p02.html
+# s32i3p04 - 32x32 paletted file, interlaced
+== s32i3p04.png s32_3p04.html
+# s32n3p04 - 32x32 paletted file, no interlacing
+== s32n3p04.png s32_3p04.html
+# s33i3p04 - 33x33 paletted file, interlaced
+== s33i3p04.png s33_3p04.html
+# s33n3p04 - 33x33 paletted file, no interlacing
+== s33n3p04.png s33_3p04.html
+# s34i3p04 - 34x34 paletted file, interlaced
+== s34i3p04.png s34_3p04.html
+# s34n3p04 - 34x34 paletted file, no interlacing
+== s34n3p04.png s34_3p04.html
+# s35i3p04 - 35x35 paletted file, interlaced
+== s35i3p04.png s35_3p04.html
+# s35n3p04 - 35x35 paletted file, no interlacing
+== s35n3p04.png s35_3p04.html
+# s36i3p04 - 36x36 paletted file, interlaced
+== s36i3p04.png s36_3p04.html
+# s36n3p04 - 36x36 paletted file, no interlacing
+== s36n3p04.png s36_3p04.html
+# s37i3p04 - 37x37 paletted file, interlaced
+== s37i3p04.png s37_3p04.html
+# s37n3p04 - 37x37 paletted file, no interlacing
+== s37n3p04.png s37_3p04.html
+# s38i3p04 - 38x38 paletted file, interlaced
+== s38i3p04.png s38_3p04.html
+# s38n3p04 - 38x38 paletted file, no interlacing
+== s38n3p04.png s38_3p04.html
+# s39i3p04 - 39x39 paletted file, interlaced
+== s39i3p04.png s39_3p04.html
+# s39n3p04 - 39x39 paletted file, no interlacing
+== s39n3p04.png s39_3p04.html
+# s40i3p04 - 40x40 paletted file, interlaced
+== s40i3p04.png s40_3p04.html
+# s40n3p04 - 40x40 paletted file, no interlacing
+== s40n3p04.png s40_3p04.html
diff --git a/image/test/reftest/pngsuite-oddsizes/s01_3p01.html b/image/test/reftest/pngsuite-oddsizes/s01_3p01.html
new file mode 100644
index 0000000000..f38d98f1a6
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s01_3p01.html
@@ -0,0 +1,9 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='1' height='1'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s01i3p01.png b/image/test/reftest/pngsuite-oddsizes/s01i3p01.png
new file mode 100644
index 0000000000..6c0fad1fc9
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s01i3p01.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s01n3p01.png b/image/test/reftest/pngsuite-oddsizes/s01n3p01.png
new file mode 100644
index 0000000000..cb2c8c7826
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s01n3p01.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s02_3p01.html b/image/test/reftest/pngsuite-oddsizes/s02_3p01.html
new file mode 100644
index 0000000000..ad4660a24c
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s02_3p01.html
@@ -0,0 +1,14 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='2' height='2'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s02i3p01.png b/image/test/reftest/pngsuite-oddsizes/s02i3p01.png
new file mode 100644
index 0000000000..2defaed911
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s02i3p01.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s02n3p01.png b/image/test/reftest/pngsuite-oddsizes/s02n3p01.png
new file mode 100644
index 0000000000..2b1b669643
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s02n3p01.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s03_3p01.html b/image/test/reftest/pngsuite-oddsizes/s03_3p01.html
new file mode 100644
index 0000000000..adff34db31
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s03_3p01.html
@@ -0,0 +1,21 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='3' height='3'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s03i3p01.png b/image/test/reftest/pngsuite-oddsizes/s03i3p01.png
new file mode 100644
index 0000000000..c23fdc4631
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s03i3p01.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s03n3p01.png b/image/test/reftest/pngsuite-oddsizes/s03n3p01.png
new file mode 100644
index 0000000000..6d96ee4f87
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s03n3p01.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s04_3p01.html b/image/test/reftest/pngsuite-oddsizes/s04_3p01.html
new file mode 100644
index 0000000000..d97c2d42cc
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s04_3p01.html
@@ -0,0 +1,30 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='4' height='4'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s04i3p01.png b/image/test/reftest/pngsuite-oddsizes/s04i3p01.png
new file mode 100644
index 0000000000..0e710c2c39
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s04i3p01.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s04n3p01.png b/image/test/reftest/pngsuite-oddsizes/s04n3p01.png
new file mode 100644
index 0000000000..956396c45b
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s04n3p01.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s05_3p02.html b/image/test/reftest/pngsuite-oddsizes/s05_3p02.html
new file mode 100644
index 0000000000..e5664fb9de
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s05_3p02.html
@@ -0,0 +1,41 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='5' height='5'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s05i3p02.png b/image/test/reftest/pngsuite-oddsizes/s05i3p02.png
new file mode 100644
index 0000000000..d14cbd351a
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s05i3p02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s05n3p02.png b/image/test/reftest/pngsuite-oddsizes/s05n3p02.png
new file mode 100644
index 0000000000..bf940f0576
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s05n3p02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s06_3p02.html b/image/test/reftest/pngsuite-oddsizes/s06_3p02.html
new file mode 100644
index 0000000000..6d13dc56fc
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s06_3p02.html
@@ -0,0 +1,54 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='6' height='6'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s06i3p02.png b/image/test/reftest/pngsuite-oddsizes/s06i3p02.png
new file mode 100644
index 0000000000..456ada3200
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s06i3p02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s06n3p02.png b/image/test/reftest/pngsuite-oddsizes/s06n3p02.png
new file mode 100644
index 0000000000..501064dc25
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s06n3p02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s07_3p02.html b/image/test/reftest/pngsuite-oddsizes/s07_3p02.html
new file mode 100644
index 0000000000..3fc2d42a71
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s07_3p02.html
@@ -0,0 +1,69 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='7' height='7'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s07i3p02.png b/image/test/reftest/pngsuite-oddsizes/s07i3p02.png
new file mode 100644
index 0000000000..44b66bab9e
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s07i3p02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s07n3p02.png b/image/test/reftest/pngsuite-oddsizes/s07n3p02.png
new file mode 100644
index 0000000000..6a582593d6
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s07n3p02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s08_3p02.html b/image/test/reftest/pngsuite-oddsizes/s08_3p02.html
new file mode 100644
index 0000000000..52079c3195
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s08_3p02.html
@@ -0,0 +1,86 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='8' height='8'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s08i3p02.png b/image/test/reftest/pngsuite-oddsizes/s08i3p02.png
new file mode 100644
index 0000000000..acf74f3fc4
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s08i3p02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s08n3p02.png b/image/test/reftest/pngsuite-oddsizes/s08n3p02.png
new file mode 100644
index 0000000000..b7094e1b4f
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s08n3p02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s09_3p02.html b/image/test/reftest/pngsuite-oddsizes/s09_3p02.html
new file mode 100644
index 0000000000..3b994e1283
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s09_3p02.html
@@ -0,0 +1,105 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='9' height='9'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s09i3p02.png b/image/test/reftest/pngsuite-oddsizes/s09i3p02.png
new file mode 100644
index 0000000000..0bfae8e456
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s09i3p02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s09n3p02.png b/image/test/reftest/pngsuite-oddsizes/s09n3p02.png
new file mode 100644
index 0000000000..711ab82451
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s09n3p02.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s32_3p04.html b/image/test/reftest/pngsuite-oddsizes/s32_3p04.html
new file mode 100644
index 0000000000..a10399ba62
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s32_3p04.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s32i3p04.png b/image/test/reftest/pngsuite-oddsizes/s32i3p04.png
new file mode 100644
index 0000000000..0841910b72
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s32i3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s32n3p04.png b/image/test/reftest/pngsuite-oddsizes/s32n3p04.png
new file mode 100644
index 0000000000..fa58e3e3f6
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s32n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s33_3p04.html b/image/test/reftest/pngsuite-oddsizes/s33_3p04.html
new file mode 100644
index 0000000000..d845558ceb
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s33_3p04.html
@@ -0,0 +1,1161 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='33' height='33'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s33i3p04.png b/image/test/reftest/pngsuite-oddsizes/s33i3p04.png
new file mode 100644
index 0000000000..ab0dc14aba
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s33i3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s33n3p04.png b/image/test/reftest/pngsuite-oddsizes/s33n3p04.png
new file mode 100644
index 0000000000..764f1a3dc7
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s33n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s34_3p04.html b/image/test/reftest/pngsuite-oddsizes/s34_3p04.html
new file mode 100644
index 0000000000..605ff92648
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s34_3p04.html
@@ -0,0 +1,1230 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='34' height='34'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s34i3p04.png b/image/test/reftest/pngsuite-oddsizes/s34i3p04.png
new file mode 100644
index 0000000000..bd99039be4
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s34i3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s34n3p04.png b/image/test/reftest/pngsuite-oddsizes/s34n3p04.png
new file mode 100644
index 0000000000..9cbc68b3b9
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s34n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s35_3p04.html b/image/test/reftest/pngsuite-oddsizes/s35_3p04.html
new file mode 100644
index 0000000000..6a5f720a99
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s35_3p04.html
@@ -0,0 +1,1301 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='35' height='35'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s35i3p04.png b/image/test/reftest/pngsuite-oddsizes/s35i3p04.png
new file mode 100644
index 0000000000..e2a5e0a659
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s35i3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s35n3p04.png b/image/test/reftest/pngsuite-oddsizes/s35n3p04.png
new file mode 100644
index 0000000000..90b892ebaf
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s35n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s36_3p04.html b/image/test/reftest/pngsuite-oddsizes/s36_3p04.html
new file mode 100644
index 0000000000..68a5ae4be1
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s36_3p04.html
@@ -0,0 +1,1374 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='36' height='36'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s36i3p04.png b/image/test/reftest/pngsuite-oddsizes/s36i3p04.png
new file mode 100644
index 0000000000..eb61b6f9a3
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s36i3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s36n3p04.png b/image/test/reftest/pngsuite-oddsizes/s36n3p04.png
new file mode 100644
index 0000000000..b38d179774
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s36n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s37_3p04.html b/image/test/reftest/pngsuite-oddsizes/s37_3p04.html
new file mode 100644
index 0000000000..0f19b653a1
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s37_3p04.html
@@ -0,0 +1,1449 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='37' height='37'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s37i3p04.png b/image/test/reftest/pngsuite-oddsizes/s37i3p04.png
new file mode 100644
index 0000000000..6e2b1e9b79
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s37i3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s37n3p04.png b/image/test/reftest/pngsuite-oddsizes/s37n3p04.png
new file mode 100644
index 0000000000..4d3054da51
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s37n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s38_3p04.html b/image/test/reftest/pngsuite-oddsizes/s38_3p04.html
new file mode 100644
index 0000000000..38a8692988
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s38_3p04.html
@@ -0,0 +1,1526 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='38' height='38'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s38i3p04.png b/image/test/reftest/pngsuite-oddsizes/s38i3p04.png
new file mode 100644
index 0000000000..a0a8a140ad
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s38i3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s38n3p04.png b/image/test/reftest/pngsuite-oddsizes/s38n3p04.png
new file mode 100644
index 0000000000..1233ed048e
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s38n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s39_3p04.html b/image/test/reftest/pngsuite-oddsizes/s39_3p04.html
new file mode 100644
index 0000000000..6a00026dc0
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s39_3p04.html
@@ -0,0 +1,1605 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='39' height='39'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s39i3p04.png b/image/test/reftest/pngsuite-oddsizes/s39i3p04.png
new file mode 100644
index 0000000000..04fee93eae
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s39i3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s39n3p04.png b/image/test/reftest/pngsuite-oddsizes/s39n3p04.png
new file mode 100644
index 0000000000..c750100d55
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s39n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s40_3p04.html b/image/test/reftest/pngsuite-oddsizes/s40_3p04.html
new file mode 100644
index 0000000000..59b18da4d7
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s40_3p04.html
@@ -0,0 +1,1686 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='40' height='40'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(180,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,180,1)'></td>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,180,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,180,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,180,255,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(180,255,0,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-oddsizes/s40i3p04.png b/image/test/reftest/pngsuite-oddsizes/s40i3p04.png
new file mode 100644
index 0000000000..68f358b822
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s40i3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-oddsizes/s40n3p04.png b/image/test/reftest/pngsuite-oddsizes/s40n3p04.png
new file mode 100644
index 0000000000..864b6b9673
--- /dev/null
+++ b/image/test/reftest/pngsuite-oddsizes/s40n3p04.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-palettes/pp0n2c16.html b/image/test/reftest/pngsuite-palettes/pp0n2c16.html
new file mode 100644
index 0000000000..dd08f0e3d0
--- /dev/null
+++ b/image/test/reftest/pngsuite-palettes/pp0n2c16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,251,53,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,247,53,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,73,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,243,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,243,73,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,88,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,239,53,1)'></td>
+ <td width='1' style='background-color: rgba(73,239,73,1)'></td>
+ <td width='1' style='background-color: rgba(53,239,88,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,100,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,235,53,1)'></td>
+ <td width='1' style='background-color: rgba(88,235,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,235,88,1)'></td>
+ <td width='1' style='background-color: rgba(53,235,100,1)'></td>
+ <td width='1' style='background-color: rgba(0,235,111,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,231,53,1)'></td>
+ <td width='1' style='background-color: rgba(100,231,73,1)'></td>
+ <td width='1' style='background-color: rgba(88,231,88,1)'></td>
+ <td width='1' style='background-color: rgba(73,231,100,1)'></td>
+ <td width='1' style='background-color: rgba(53,231,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,231,121,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,227,53,1)'></td>
+ <td width='1' style='background-color: rgba(111,227,73,1)'></td>
+ <td width='1' style='background-color: rgba(100,227,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,227,100,1)'></td>
+ <td width='1' style='background-color: rgba(73,227,111,1)'></td>
+ <td width='1' style='background-color: rgba(53,227,121,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,130,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,223,53,1)'></td>
+ <td width='1' style='background-color: rgba(121,223,73,1)'></td>
+ <td width='1' style='background-color: rgba(111,223,88,1)'></td>
+ <td width='1' style='background-color: rgba(100,223,100,1)'></td>
+ <td width='1' style='background-color: rgba(88,223,111,1)'></td>
+ <td width='1' style='background-color: rgba(73,223,121,1)'></td>
+ <td width='1' style='background-color: rgba(53,223,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,223,138,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,218,53,1)'></td>
+ <td width='1' style='background-color: rgba(130,218,73,1)'></td>
+ <td width='1' style='background-color: rgba(121,218,88,1)'></td>
+ <td width='1' style='background-color: rgba(111,218,100,1)'></td>
+ <td width='1' style='background-color: rgba(100,218,111,1)'></td>
+ <td width='1' style='background-color: rgba(88,218,121,1)'></td>
+ <td width='1' style='background-color: rgba(73,218,130,1)'></td>
+ <td width='1' style='background-color: rgba(53,218,138,1)'></td>
+ <td width='1' style='background-color: rgba(0,218,145,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,214,53,1)'></td>
+ <td width='1' style='background-color: rgba(138,214,73,1)'></td>
+ <td width='1' style='background-color: rgba(130,214,88,1)'></td>
+ <td width='1' style='background-color: rgba(121,214,100,1)'></td>
+ <td width='1' style='background-color: rgba(111,214,111,1)'></td>
+ <td width='1' style='background-color: rgba(100,214,121,1)'></td>
+ <td width='1' style='background-color: rgba(88,214,130,1)'></td>
+ <td width='1' style='background-color: rgba(73,214,138,1)'></td>
+ <td width='1' style='background-color: rgba(53,214,145,1)'></td>
+ <td width='1' style='background-color: rgba(0,214,152,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,209,53,1)'></td>
+ <td width='1' style='background-color: rgba(145,209,73,1)'></td>
+ <td width='1' style='background-color: rgba(138,209,88,1)'></td>
+ <td width='1' style='background-color: rgba(130,209,100,1)'></td>
+ <td width='1' style='background-color: rgba(121,209,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,209,121,1)'></td>
+ <td width='1' style='background-color: rgba(100,209,130,1)'></td>
+ <td width='1' style='background-color: rgba(88,209,138,1)'></td>
+ <td width='1' style='background-color: rgba(73,209,145,1)'></td>
+ <td width='1' style='background-color: rgba(53,209,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,159,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,204,53,1)'></td>
+ <td width='1' style='background-color: rgba(152,204,73,1)'></td>
+ <td width='1' style='background-color: rgba(145,204,88,1)'></td>
+ <td width='1' style='background-color: rgba(138,204,100,1)'></td>
+ <td width='1' style='background-color: rgba(130,204,111,1)'></td>
+ <td width='1' style='background-color: rgba(121,204,121,1)'></td>
+ <td width='1' style='background-color: rgba(111,204,130,1)'></td>
+ <td width='1' style='background-color: rgba(100,204,138,1)'></td>
+ <td width='1' style='background-color: rgba(88,204,145,1)'></td>
+ <td width='1' style='background-color: rgba(73,204,152,1)'></td>
+ <td width='1' style='background-color: rgba(53,204,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,204,166,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,199,53,1)'></td>
+ <td width='1' style='background-color: rgba(159,199,73,1)'></td>
+ <td width='1' style='background-color: rgba(152,199,88,1)'></td>
+ <td width='1' style='background-color: rgba(145,199,100,1)'></td>
+ <td width='1' style='background-color: rgba(138,199,111,1)'></td>
+ <td width='1' style='background-color: rgba(130,199,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,199,130,1)'></td>
+ <td width='1' style='background-color: rgba(111,199,138,1)'></td>
+ <td width='1' style='background-color: rgba(100,199,145,1)'></td>
+ <td width='1' style='background-color: rgba(88,199,152,1)'></td>
+ <td width='1' style='background-color: rgba(73,199,159,1)'></td>
+ <td width='1' style='background-color: rgba(53,199,166,1)'></td>
+ <td width='1' style='background-color: rgba(0,199,172,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,194,53,1)'></td>
+ <td width='1' style='background-color: rgba(166,194,73,1)'></td>
+ <td width='1' style='background-color: rgba(159,194,88,1)'></td>
+ <td width='1' style='background-color: rgba(152,194,100,1)'></td>
+ <td width='1' style='background-color: rgba(145,194,111,1)'></td>
+ <td width='1' style='background-color: rgba(138,194,121,1)'></td>
+ <td width='1' style='background-color: rgba(130,194,130,1)'></td>
+ <td width='1' style='background-color: rgba(121,194,138,1)'></td>
+ <td width='1' style='background-color: rgba(111,194,145,1)'></td>
+ <td width='1' style='background-color: rgba(100,194,152,1)'></td>
+ <td width='1' style='background-color: rgba(88,194,159,1)'></td>
+ <td width='1' style='background-color: rgba(73,194,166,1)'></td>
+ <td width='1' style='background-color: rgba(53,194,172,1)'></td>
+ <td width='1' style='background-color: rgba(0,194,178,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,189,53,1)'></td>
+ <td width='1' style='background-color: rgba(172,189,73,1)'></td>
+ <td width='1' style='background-color: rgba(166,189,88,1)'></td>
+ <td width='1' style='background-color: rgba(159,189,100,1)'></td>
+ <td width='1' style='background-color: rgba(152,189,111,1)'></td>
+ <td width='1' style='background-color: rgba(145,189,121,1)'></td>
+ <td width='1' style='background-color: rgba(138,189,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,189,138,1)'></td>
+ <td width='1' style='background-color: rgba(121,189,145,1)'></td>
+ <td width='1' style='background-color: rgba(111,189,152,1)'></td>
+ <td width='1' style='background-color: rgba(100,189,159,1)'></td>
+ <td width='1' style='background-color: rgba(88,189,166,1)'></td>
+ <td width='1' style='background-color: rgba(73,189,172,1)'></td>
+ <td width='1' style='background-color: rgba(53,189,178,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,183,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,53,1)'></td>
+ <td width='1' style='background-color: rgba(178,183,73,1)'></td>
+ <td width='1' style='background-color: rgba(172,183,88,1)'></td>
+ <td width='1' style='background-color: rgba(166,183,100,1)'></td>
+ <td width='1' style='background-color: rgba(159,183,111,1)'></td>
+ <td width='1' style='background-color: rgba(152,183,121,1)'></td>
+ <td width='1' style='background-color: rgba(145,183,130,1)'></td>
+ <td width='1' style='background-color: rgba(138,183,138,1)'></td>
+ <td width='1' style='background-color: rgba(130,183,145,1)'></td>
+ <td width='1' style='background-color: rgba(121,183,152,1)'></td>
+ <td width='1' style='background-color: rgba(111,183,159,1)'></td>
+ <td width='1' style='background-color: rgba(100,183,166,1)'></td>
+ <td width='1' style='background-color: rgba(88,183,172,1)'></td>
+ <td width='1' style='background-color: rgba(73,183,178,1)'></td>
+ <td width='1' style='background-color: rgba(53,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,183,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,178,53,1)'></td>
+ <td width='1' style='background-color: rgba(183,178,73,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,88,1)'></td>
+ <td width='1' style='background-color: rgba(172,178,100,1)'></td>
+ <td width='1' style='background-color: rgba(166,178,111,1)'></td>
+ <td width='1' style='background-color: rgba(159,178,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,178,130,1)'></td>
+ <td width='1' style='background-color: rgba(145,178,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,178,145,1)'></td>
+ <td width='1' style='background-color: rgba(130,178,152,1)'></td>
+ <td width='1' style='background-color: rgba(121,178,159,1)'></td>
+ <td width='1' style='background-color: rgba(111,178,166,1)'></td>
+ <td width='1' style='background-color: rgba(100,178,172,1)'></td>
+ <td width='1' style='background-color: rgba(88,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(73,178,183,1)'></td>
+ <td width='1' style='background-color: rgba(53,178,189,1)'></td>
+ <td width='1' style='background-color: rgba(0,178,194,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,172,53,1)'></td>
+ <td width='1' style='background-color: rgba(189,172,73,1)'></td>
+ <td width='1' style='background-color: rgba(183,172,88,1)'></td>
+ <td width='1' style='background-color: rgba(178,172,100,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,111,1)'></td>
+ <td width='1' style='background-color: rgba(166,172,121,1)'></td>
+ <td width='1' style='background-color: rgba(159,172,130,1)'></td>
+ <td width='1' style='background-color: rgba(152,172,138,1)'></td>
+ <td width='1' style='background-color: rgba(145,172,145,1)'></td>
+ <td width='1' style='background-color: rgba(138,172,152,1)'></td>
+ <td width='1' style='background-color: rgba(130,172,159,1)'></td>
+ <td width='1' style='background-color: rgba(121,172,166,1)'></td>
+ <td width='1' style='background-color: rgba(111,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(100,172,178,1)'></td>
+ <td width='1' style='background-color: rgba(88,172,183,1)'></td>
+ <td width='1' style='background-color: rgba(73,172,189,1)'></td>
+ <td width='1' style='background-color: rgba(53,172,194,1)'></td>
+ <td width='1' style='background-color: rgba(0,172,199,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,166,53,1)'></td>
+ <td width='1' style='background-color: rgba(194,166,73,1)'></td>
+ <td width='1' style='background-color: rgba(189,166,88,1)'></td>
+ <td width='1' style='background-color: rgba(183,166,100,1)'></td>
+ <td width='1' style='background-color: rgba(178,166,111,1)'></td>
+ <td width='1' style='background-color: rgba(172,166,121,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,130,1)'></td>
+ <td width='1' style='background-color: rgba(159,166,138,1)'></td>
+ <td width='1' style='background-color: rgba(152,166,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,166,152,1)'></td>
+ <td width='1' style='background-color: rgba(138,166,159,1)'></td>
+ <td width='1' style='background-color: rgba(130,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(121,166,172,1)'></td>
+ <td width='1' style='background-color: rgba(111,166,178,1)'></td>
+ <td width='1' style='background-color: rgba(100,166,183,1)'></td>
+ <td width='1' style='background-color: rgba(88,166,189,1)'></td>
+ <td width='1' style='background-color: rgba(73,166,194,1)'></td>
+ <td width='1' style='background-color: rgba(53,166,199,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,204,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,159,53,1)'></td>
+ <td width='1' style='background-color: rgba(199,159,73,1)'></td>
+ <td width='1' style='background-color: rgba(194,159,88,1)'></td>
+ <td width='1' style='background-color: rgba(189,159,100,1)'></td>
+ <td width='1' style='background-color: rgba(183,159,111,1)'></td>
+ <td width='1' style='background-color: rgba(178,159,121,1)'></td>
+ <td width='1' style='background-color: rgba(172,159,130,1)'></td>
+ <td width='1' style='background-color: rgba(166,159,138,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,145,1)'></td>
+ <td width='1' style='background-color: rgba(152,159,152,1)'></td>
+ <td width='1' style='background-color: rgba(145,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(138,159,166,1)'></td>
+ <td width='1' style='background-color: rgba(130,159,172,1)'></td>
+ <td width='1' style='background-color: rgba(121,159,178,1)'></td>
+ <td width='1' style='background-color: rgba(111,159,183,1)'></td>
+ <td width='1' style='background-color: rgba(100,159,189,1)'></td>
+ <td width='1' style='background-color: rgba(88,159,194,1)'></td>
+ <td width='1' style='background-color: rgba(73,159,199,1)'></td>
+ <td width='1' style='background-color: rgba(53,159,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,159,209,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,152,53,1)'></td>
+ <td width='1' style='background-color: rgba(204,152,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,152,88,1)'></td>
+ <td width='1' style='background-color: rgba(194,152,100,1)'></td>
+ <td width='1' style='background-color: rgba(189,152,111,1)'></td>
+ <td width='1' style='background-color: rgba(183,152,121,1)'></td>
+ <td width='1' style='background-color: rgba(178,152,130,1)'></td>
+ <td width='1' style='background-color: rgba(172,152,138,1)'></td>
+ <td width='1' style='background-color: rgba(166,152,145,1)'></td>
+ <td width='1' style='background-color: rgba(159,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,159,1)'></td>
+ <td width='1' style='background-color: rgba(145,152,166,1)'></td>
+ <td width='1' style='background-color: rgba(138,152,172,1)'></td>
+ <td width='1' style='background-color: rgba(130,152,178,1)'></td>
+ <td width='1' style='background-color: rgba(121,152,183,1)'></td>
+ <td width='1' style='background-color: rgba(111,152,189,1)'></td>
+ <td width='1' style='background-color: rgba(100,152,194,1)'></td>
+ <td width='1' style='background-color: rgba(88,152,199,1)'></td>
+ <td width='1' style='background-color: rgba(73,152,204,1)'></td>
+ <td width='1' style='background-color: rgba(53,152,209,1)'></td>
+ <td width='1' style='background-color: rgba(0,152,214,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,145,53,1)'></td>
+ <td width='1' style='background-color: rgba(209,145,73,1)'></td>
+ <td width='1' style='background-color: rgba(204,145,88,1)'></td>
+ <td width='1' style='background-color: rgba(199,145,100,1)'></td>
+ <td width='1' style='background-color: rgba(194,145,111,1)'></td>
+ <td width='1' style='background-color: rgba(189,145,121,1)'></td>
+ <td width='1' style='background-color: rgba(183,145,130,1)'></td>
+ <td width='1' style='background-color: rgba(178,145,138,1)'></td>
+ <td width='1' style='background-color: rgba(172,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(166,145,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,145,159,1)'></td>
+ <td width='1' style='background-color: rgba(152,145,166,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,172,1)'></td>
+ <td width='1' style='background-color: rgba(138,145,178,1)'></td>
+ <td width='1' style='background-color: rgba(130,145,183,1)'></td>
+ <td width='1' style='background-color: rgba(121,145,189,1)'></td>
+ <td width='1' style='background-color: rgba(111,145,194,1)'></td>
+ <td width='1' style='background-color: rgba(100,145,199,1)'></td>
+ <td width='1' style='background-color: rgba(88,145,204,1)'></td>
+ <td width='1' style='background-color: rgba(73,145,209,1)'></td>
+ <td width='1' style='background-color: rgba(53,145,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,218,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,138,53,1)'></td>
+ <td width='1' style='background-color: rgba(214,138,73,1)'></td>
+ <td width='1' style='background-color: rgba(209,138,88,1)'></td>
+ <td width='1' style='background-color: rgba(204,138,100,1)'></td>
+ <td width='1' style='background-color: rgba(199,138,111,1)'></td>
+ <td width='1' style='background-color: rgba(194,138,121,1)'></td>
+ <td width='1' style='background-color: rgba(189,138,130,1)'></td>
+ <td width='1' style='background-color: rgba(183,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(178,138,145,1)'></td>
+ <td width='1' style='background-color: rgba(172,138,152,1)'></td>
+ <td width='1' style='background-color: rgba(166,138,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,138,166,1)'></td>
+ <td width='1' style='background-color: rgba(152,138,172,1)'></td>
+ <td width='1' style='background-color: rgba(145,138,178,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,183,1)'></td>
+ <td width='1' style='background-color: rgba(130,138,189,1)'></td>
+ <td width='1' style='background-color: rgba(121,138,194,1)'></td>
+ <td width='1' style='background-color: rgba(111,138,199,1)'></td>
+ <td width='1' style='background-color: rgba(100,138,204,1)'></td>
+ <td width='1' style='background-color: rgba(88,138,209,1)'></td>
+ <td width='1' style='background-color: rgba(73,138,214,1)'></td>
+ <td width='1' style='background-color: rgba(53,138,218,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,130,53,1)'></td>
+ <td width='1' style='background-color: rgba(218,130,73,1)'></td>
+ <td width='1' style='background-color: rgba(214,130,88,1)'></td>
+ <td width='1' style='background-color: rgba(209,130,100,1)'></td>
+ <td width='1' style='background-color: rgba(204,130,111,1)'></td>
+ <td width='1' style='background-color: rgba(199,130,121,1)'></td>
+ <td width='1' style='background-color: rgba(194,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(189,130,138,1)'></td>
+ <td width='1' style='background-color: rgba(183,130,145,1)'></td>
+ <td width='1' style='background-color: rgba(178,130,152,1)'></td>
+ <td width='1' style='background-color: rgba(172,130,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,130,166,1)'></td>
+ <td width='1' style='background-color: rgba(159,130,172,1)'></td>
+ <td width='1' style='background-color: rgba(152,130,178,1)'></td>
+ <td width='1' style='background-color: rgba(145,130,183,1)'></td>
+ <td width='1' style='background-color: rgba(138,130,189,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,194,1)'></td>
+ <td width='1' style='background-color: rgba(121,130,199,1)'></td>
+ <td width='1' style='background-color: rgba(111,130,204,1)'></td>
+ <td width='1' style='background-color: rgba(100,130,209,1)'></td>
+ <td width='1' style='background-color: rgba(88,130,214,1)'></td>
+ <td width='1' style='background-color: rgba(73,130,218,1)'></td>
+ <td width='1' style='background-color: rgba(53,130,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,130,227,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,121,53,1)'></td>
+ <td width='1' style='background-color: rgba(223,121,73,1)'></td>
+ <td width='1' style='background-color: rgba(218,121,88,1)'></td>
+ <td width='1' style='background-color: rgba(214,121,100,1)'></td>
+ <td width='1' style='background-color: rgba(209,121,111,1)'></td>
+ <td width='1' style='background-color: rgba(204,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(199,121,130,1)'></td>
+ <td width='1' style='background-color: rgba(194,121,138,1)'></td>
+ <td width='1' style='background-color: rgba(189,121,145,1)'></td>
+ <td width='1' style='background-color: rgba(183,121,152,1)'></td>
+ <td width='1' style='background-color: rgba(178,121,159,1)'></td>
+ <td width='1' style='background-color: rgba(172,121,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,121,172,1)'></td>
+ <td width='1' style='background-color: rgba(159,121,178,1)'></td>
+ <td width='1' style='background-color: rgba(152,121,183,1)'></td>
+ <td width='1' style='background-color: rgba(145,121,189,1)'></td>
+ <td width='1' style='background-color: rgba(138,121,194,1)'></td>
+ <td width='1' style='background-color: rgba(130,121,199,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,204,1)'></td>
+ <td width='1' style='background-color: rgba(111,121,209,1)'></td>
+ <td width='1' style='background-color: rgba(100,121,214,1)'></td>
+ <td width='1' style='background-color: rgba(88,121,218,1)'></td>
+ <td width='1' style='background-color: rgba(73,121,223,1)'></td>
+ <td width='1' style='background-color: rgba(53,121,227,1)'></td>
+ <td width='1' style='background-color: rgba(0,121,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,111,53,1)'></td>
+ <td width='1' style='background-color: rgba(227,111,73,1)'></td>
+ <td width='1' style='background-color: rgba(223,111,88,1)'></td>
+ <td width='1' style='background-color: rgba(218,111,100,1)'></td>
+ <td width='1' style='background-color: rgba(214,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(209,111,121,1)'></td>
+ <td width='1' style='background-color: rgba(204,111,130,1)'></td>
+ <td width='1' style='background-color: rgba(199,111,138,1)'></td>
+ <td width='1' style='background-color: rgba(194,111,145,1)'></td>
+ <td width='1' style='background-color: rgba(189,111,152,1)'></td>
+ <td width='1' style='background-color: rgba(183,111,159,1)'></td>
+ <td width='1' style='background-color: rgba(178,111,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,111,172,1)'></td>
+ <td width='1' style='background-color: rgba(166,111,178,1)'></td>
+ <td width='1' style='background-color: rgba(159,111,183,1)'></td>
+ <td width='1' style='background-color: rgba(152,111,189,1)'></td>
+ <td width='1' style='background-color: rgba(145,111,194,1)'></td>
+ <td width='1' style='background-color: rgba(138,111,199,1)'></td>
+ <td width='1' style='background-color: rgba(130,111,204,1)'></td>
+ <td width='1' style='background-color: rgba(121,111,209,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,214,1)'></td>
+ <td width='1' style='background-color: rgba(100,111,218,1)'></td>
+ <td width='1' style='background-color: rgba(88,111,223,1)'></td>
+ <td width='1' style='background-color: rgba(73,111,227,1)'></td>
+ <td width='1' style='background-color: rgba(53,111,231,1)'></td>
+ <td width='1' style='background-color: rgba(0,111,235,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,100,53,1)'></td>
+ <td width='1' style='background-color: rgba(231,100,73,1)'></td>
+ <td width='1' style='background-color: rgba(227,100,88,1)'></td>
+ <td width='1' style='background-color: rgba(223,100,100,1)'></td>
+ <td width='1' style='background-color: rgba(218,100,111,1)'></td>
+ <td width='1' style='background-color: rgba(214,100,121,1)'></td>
+ <td width='1' style='background-color: rgba(209,100,130,1)'></td>
+ <td width='1' style='background-color: rgba(204,100,138,1)'></td>
+ <td width='1' style='background-color: rgba(199,100,145,1)'></td>
+ <td width='1' style='background-color: rgba(194,100,152,1)'></td>
+ <td width='1' style='background-color: rgba(189,100,159,1)'></td>
+ <td width='1' style='background-color: rgba(183,100,166,1)'></td>
+ <td width='1' style='background-color: rgba(178,100,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,100,178,1)'></td>
+ <td width='1' style='background-color: rgba(166,100,183,1)'></td>
+ <td width='1' style='background-color: rgba(159,100,189,1)'></td>
+ <td width='1' style='background-color: rgba(152,100,194,1)'></td>
+ <td width='1' style='background-color: rgba(145,100,199,1)'></td>
+ <td width='1' style='background-color: rgba(138,100,204,1)'></td>
+ <td width='1' style='background-color: rgba(130,100,209,1)'></td>
+ <td width='1' style='background-color: rgba(121,100,214,1)'></td>
+ <td width='1' style='background-color: rgba(111,100,218,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,223,1)'></td>
+ <td width='1' style='background-color: rgba(88,100,227,1)'></td>
+ <td width='1' style='background-color: rgba(73,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(53,100,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,100,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,88,53,1)'></td>
+ <td width='1' style='background-color: rgba(235,88,73,1)'></td>
+ <td width='1' style='background-color: rgba(231,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(227,88,100,1)'></td>
+ <td width='1' style='background-color: rgba(223,88,111,1)'></td>
+ <td width='1' style='background-color: rgba(218,88,121,1)'></td>
+ <td width='1' style='background-color: rgba(214,88,130,1)'></td>
+ <td width='1' style='background-color: rgba(209,88,138,1)'></td>
+ <td width='1' style='background-color: rgba(204,88,145,1)'></td>
+ <td width='1' style='background-color: rgba(199,88,152,1)'></td>
+ <td width='1' style='background-color: rgba(194,88,159,1)'></td>
+ <td width='1' style='background-color: rgba(189,88,166,1)'></td>
+ <td width='1' style='background-color: rgba(183,88,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,88,178,1)'></td>
+ <td width='1' style='background-color: rgba(172,88,183,1)'></td>
+ <td width='1' style='background-color: rgba(166,88,189,1)'></td>
+ <td width='1' style='background-color: rgba(159,88,194,1)'></td>
+ <td width='1' style='background-color: rgba(152,88,199,1)'></td>
+ <td width='1' style='background-color: rgba(145,88,204,1)'></td>
+ <td width='1' style='background-color: rgba(138,88,209,1)'></td>
+ <td width='1' style='background-color: rgba(130,88,214,1)'></td>
+ <td width='1' style='background-color: rgba(121,88,218,1)'></td>
+ <td width='1' style='background-color: rgba(111,88,223,1)'></td>
+ <td width='1' style='background-color: rgba(100,88,227,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,231,1)'></td>
+ <td width='1' style='background-color: rgba(73,88,235,1)'></td>
+ <td width='1' style='background-color: rgba(53,88,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,243,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,73,53,1)'></td>
+ <td width='1' style='background-color: rgba(239,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(235,73,88,1)'></td>
+ <td width='1' style='background-color: rgba(231,73,100,1)'></td>
+ <td width='1' style='background-color: rgba(227,73,111,1)'></td>
+ <td width='1' style='background-color: rgba(223,73,121,1)'></td>
+ <td width='1' style='background-color: rgba(218,73,130,1)'></td>
+ <td width='1' style='background-color: rgba(214,73,138,1)'></td>
+ <td width='1' style='background-color: rgba(209,73,145,1)'></td>
+ <td width='1' style='background-color: rgba(204,73,152,1)'></td>
+ <td width='1' style='background-color: rgba(199,73,159,1)'></td>
+ <td width='1' style='background-color: rgba(194,73,166,1)'></td>
+ <td width='1' style='background-color: rgba(189,73,172,1)'></td>
+ <td width='1' style='background-color: rgba(183,73,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,73,183,1)'></td>
+ <td width='1' style='background-color: rgba(172,73,189,1)'></td>
+ <td width='1' style='background-color: rgba(166,73,194,1)'></td>
+ <td width='1' style='background-color: rgba(159,73,199,1)'></td>
+ <td width='1' style='background-color: rgba(152,73,204,1)'></td>
+ <td width='1' style='background-color: rgba(145,73,209,1)'></td>
+ <td width='1' style='background-color: rgba(138,73,214,1)'></td>
+ <td width='1' style='background-color: rgba(130,73,218,1)'></td>
+ <td width='1' style='background-color: rgba(121,73,223,1)'></td>
+ <td width='1' style='background-color: rgba(111,73,227,1)'></td>
+ <td width='1' style='background-color: rgba(100,73,231,1)'></td>
+ <td width='1' style='background-color: rgba(88,73,235,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,239,1)'></td>
+ <td width='1' style='background-color: rgba(53,73,243,1)'></td>
+ <td width='1' style='background-color: rgba(0,73,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,53,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,53,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(243,53,73,1)'></td>
+ <td width='1' style='background-color: rgba(239,53,88,1)'></td>
+ <td width='1' style='background-color: rgba(235,53,100,1)'></td>
+ <td width='1' style='background-color: rgba(231,53,111,1)'></td>
+ <td width='1' style='background-color: rgba(227,53,121,1)'></td>
+ <td width='1' style='background-color: rgba(223,53,130,1)'></td>
+ <td width='1' style='background-color: rgba(218,53,138,1)'></td>
+ <td width='1' style='background-color: rgba(214,53,145,1)'></td>
+ <td width='1' style='background-color: rgba(209,53,152,1)'></td>
+ <td width='1' style='background-color: rgba(204,53,159,1)'></td>
+ <td width='1' style='background-color: rgba(199,53,166,1)'></td>
+ <td width='1' style='background-color: rgba(194,53,172,1)'></td>
+ <td width='1' style='background-color: rgba(189,53,178,1)'></td>
+ <td width='1' style='background-color: rgba(183,53,183,1)'></td>
+ <td width='1' style='background-color: rgba(178,53,189,1)'></td>
+ <td width='1' style='background-color: rgba(172,53,194,1)'></td>
+ <td width='1' style='background-color: rgba(166,53,199,1)'></td>
+ <td width='1' style='background-color: rgba(159,53,204,1)'></td>
+ <td width='1' style='background-color: rgba(152,53,209,1)'></td>
+ <td width='1' style='background-color: rgba(145,53,214,1)'></td>
+ <td width='1' style='background-color: rgba(138,53,218,1)'></td>
+ <td width='1' style='background-color: rgba(130,53,223,1)'></td>
+ <td width='1' style='background-color: rgba(121,53,227,1)'></td>
+ <td width='1' style='background-color: rgba(111,53,231,1)'></td>
+ <td width='1' style='background-color: rgba(100,53,235,1)'></td>
+ <td width='1' style='background-color: rgba(88,53,239,1)'></td>
+ <td width='1' style='background-color: rgba(73,53,243,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,251,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,53,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,73,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,88,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,100,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,111,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,121,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,130,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,138,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,145,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,152,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,159,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,166,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,172,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,178,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,189,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,194,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,199,1)'></td>
+ <td width='1' style='background-color: rgba(166,0,204,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,209,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,214,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,218,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,223,1)'></td>
+ <td width='1' style='background-color: rgba(130,0,227,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,231,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,235,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,239,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,243,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,251,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-palettes/pp0n2c16.png b/image/test/reftest/pngsuite-palettes/pp0n2c16.png
new file mode 100644
index 0000000000..8f2aad7335
--- /dev/null
+++ b/image/test/reftest/pngsuite-palettes/pp0n2c16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-palettes/pp0n6a08.png b/image/test/reftest/pngsuite-palettes/pp0n6a08.png
new file mode 100644
index 0000000000..4ed7a30e4d
--- /dev/null
+++ b/image/test/reftest/pngsuite-palettes/pp0n6a08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-palettes/ps1n0g08.html b/image/test/reftest/pngsuite-palettes/ps1n0g08.html
new file mode 100644
index 0000000000..5aaf11cabb
--- /dev/null
+++ b/image/test/reftest/pngsuite-palettes/ps1n0g08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-palettes/ps1n0g08.png b/image/test/reftest/pngsuite-palettes/ps1n0g08.png
new file mode 100644
index 0000000000..2053df2ba3
--- /dev/null
+++ b/image/test/reftest/pngsuite-palettes/ps1n0g08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-palettes/ps1n2c16.html b/image/test/reftest/pngsuite-palettes/ps1n2c16.html
new file mode 100644
index 0000000000..dd08f0e3d0
--- /dev/null
+++ b/image/test/reftest/pngsuite-palettes/ps1n2c16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,251,53,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,247,53,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,73,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,243,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,243,73,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,88,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,239,53,1)'></td>
+ <td width='1' style='background-color: rgba(73,239,73,1)'></td>
+ <td width='1' style='background-color: rgba(53,239,88,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,100,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,235,53,1)'></td>
+ <td width='1' style='background-color: rgba(88,235,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,235,88,1)'></td>
+ <td width='1' style='background-color: rgba(53,235,100,1)'></td>
+ <td width='1' style='background-color: rgba(0,235,111,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,231,53,1)'></td>
+ <td width='1' style='background-color: rgba(100,231,73,1)'></td>
+ <td width='1' style='background-color: rgba(88,231,88,1)'></td>
+ <td width='1' style='background-color: rgba(73,231,100,1)'></td>
+ <td width='1' style='background-color: rgba(53,231,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,231,121,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,227,53,1)'></td>
+ <td width='1' style='background-color: rgba(111,227,73,1)'></td>
+ <td width='1' style='background-color: rgba(100,227,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,227,100,1)'></td>
+ <td width='1' style='background-color: rgba(73,227,111,1)'></td>
+ <td width='1' style='background-color: rgba(53,227,121,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,130,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,223,53,1)'></td>
+ <td width='1' style='background-color: rgba(121,223,73,1)'></td>
+ <td width='1' style='background-color: rgba(111,223,88,1)'></td>
+ <td width='1' style='background-color: rgba(100,223,100,1)'></td>
+ <td width='1' style='background-color: rgba(88,223,111,1)'></td>
+ <td width='1' style='background-color: rgba(73,223,121,1)'></td>
+ <td width='1' style='background-color: rgba(53,223,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,223,138,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,218,53,1)'></td>
+ <td width='1' style='background-color: rgba(130,218,73,1)'></td>
+ <td width='1' style='background-color: rgba(121,218,88,1)'></td>
+ <td width='1' style='background-color: rgba(111,218,100,1)'></td>
+ <td width='1' style='background-color: rgba(100,218,111,1)'></td>
+ <td width='1' style='background-color: rgba(88,218,121,1)'></td>
+ <td width='1' style='background-color: rgba(73,218,130,1)'></td>
+ <td width='1' style='background-color: rgba(53,218,138,1)'></td>
+ <td width='1' style='background-color: rgba(0,218,145,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,214,53,1)'></td>
+ <td width='1' style='background-color: rgba(138,214,73,1)'></td>
+ <td width='1' style='background-color: rgba(130,214,88,1)'></td>
+ <td width='1' style='background-color: rgba(121,214,100,1)'></td>
+ <td width='1' style='background-color: rgba(111,214,111,1)'></td>
+ <td width='1' style='background-color: rgba(100,214,121,1)'></td>
+ <td width='1' style='background-color: rgba(88,214,130,1)'></td>
+ <td width='1' style='background-color: rgba(73,214,138,1)'></td>
+ <td width='1' style='background-color: rgba(53,214,145,1)'></td>
+ <td width='1' style='background-color: rgba(0,214,152,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,209,53,1)'></td>
+ <td width='1' style='background-color: rgba(145,209,73,1)'></td>
+ <td width='1' style='background-color: rgba(138,209,88,1)'></td>
+ <td width='1' style='background-color: rgba(130,209,100,1)'></td>
+ <td width='1' style='background-color: rgba(121,209,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,209,121,1)'></td>
+ <td width='1' style='background-color: rgba(100,209,130,1)'></td>
+ <td width='1' style='background-color: rgba(88,209,138,1)'></td>
+ <td width='1' style='background-color: rgba(73,209,145,1)'></td>
+ <td width='1' style='background-color: rgba(53,209,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,159,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,204,53,1)'></td>
+ <td width='1' style='background-color: rgba(152,204,73,1)'></td>
+ <td width='1' style='background-color: rgba(145,204,88,1)'></td>
+ <td width='1' style='background-color: rgba(138,204,100,1)'></td>
+ <td width='1' style='background-color: rgba(130,204,111,1)'></td>
+ <td width='1' style='background-color: rgba(121,204,121,1)'></td>
+ <td width='1' style='background-color: rgba(111,204,130,1)'></td>
+ <td width='1' style='background-color: rgba(100,204,138,1)'></td>
+ <td width='1' style='background-color: rgba(88,204,145,1)'></td>
+ <td width='1' style='background-color: rgba(73,204,152,1)'></td>
+ <td width='1' style='background-color: rgba(53,204,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,204,166,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,199,53,1)'></td>
+ <td width='1' style='background-color: rgba(159,199,73,1)'></td>
+ <td width='1' style='background-color: rgba(152,199,88,1)'></td>
+ <td width='1' style='background-color: rgba(145,199,100,1)'></td>
+ <td width='1' style='background-color: rgba(138,199,111,1)'></td>
+ <td width='1' style='background-color: rgba(130,199,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,199,130,1)'></td>
+ <td width='1' style='background-color: rgba(111,199,138,1)'></td>
+ <td width='1' style='background-color: rgba(100,199,145,1)'></td>
+ <td width='1' style='background-color: rgba(88,199,152,1)'></td>
+ <td width='1' style='background-color: rgba(73,199,159,1)'></td>
+ <td width='1' style='background-color: rgba(53,199,166,1)'></td>
+ <td width='1' style='background-color: rgba(0,199,172,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,194,53,1)'></td>
+ <td width='1' style='background-color: rgba(166,194,73,1)'></td>
+ <td width='1' style='background-color: rgba(159,194,88,1)'></td>
+ <td width='1' style='background-color: rgba(152,194,100,1)'></td>
+ <td width='1' style='background-color: rgba(145,194,111,1)'></td>
+ <td width='1' style='background-color: rgba(138,194,121,1)'></td>
+ <td width='1' style='background-color: rgba(130,194,130,1)'></td>
+ <td width='1' style='background-color: rgba(121,194,138,1)'></td>
+ <td width='1' style='background-color: rgba(111,194,145,1)'></td>
+ <td width='1' style='background-color: rgba(100,194,152,1)'></td>
+ <td width='1' style='background-color: rgba(88,194,159,1)'></td>
+ <td width='1' style='background-color: rgba(73,194,166,1)'></td>
+ <td width='1' style='background-color: rgba(53,194,172,1)'></td>
+ <td width='1' style='background-color: rgba(0,194,178,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,189,53,1)'></td>
+ <td width='1' style='background-color: rgba(172,189,73,1)'></td>
+ <td width='1' style='background-color: rgba(166,189,88,1)'></td>
+ <td width='1' style='background-color: rgba(159,189,100,1)'></td>
+ <td width='1' style='background-color: rgba(152,189,111,1)'></td>
+ <td width='1' style='background-color: rgba(145,189,121,1)'></td>
+ <td width='1' style='background-color: rgba(138,189,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,189,138,1)'></td>
+ <td width='1' style='background-color: rgba(121,189,145,1)'></td>
+ <td width='1' style='background-color: rgba(111,189,152,1)'></td>
+ <td width='1' style='background-color: rgba(100,189,159,1)'></td>
+ <td width='1' style='background-color: rgba(88,189,166,1)'></td>
+ <td width='1' style='background-color: rgba(73,189,172,1)'></td>
+ <td width='1' style='background-color: rgba(53,189,178,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,183,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,53,1)'></td>
+ <td width='1' style='background-color: rgba(178,183,73,1)'></td>
+ <td width='1' style='background-color: rgba(172,183,88,1)'></td>
+ <td width='1' style='background-color: rgba(166,183,100,1)'></td>
+ <td width='1' style='background-color: rgba(159,183,111,1)'></td>
+ <td width='1' style='background-color: rgba(152,183,121,1)'></td>
+ <td width='1' style='background-color: rgba(145,183,130,1)'></td>
+ <td width='1' style='background-color: rgba(138,183,138,1)'></td>
+ <td width='1' style='background-color: rgba(130,183,145,1)'></td>
+ <td width='1' style='background-color: rgba(121,183,152,1)'></td>
+ <td width='1' style='background-color: rgba(111,183,159,1)'></td>
+ <td width='1' style='background-color: rgba(100,183,166,1)'></td>
+ <td width='1' style='background-color: rgba(88,183,172,1)'></td>
+ <td width='1' style='background-color: rgba(73,183,178,1)'></td>
+ <td width='1' style='background-color: rgba(53,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,183,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,178,53,1)'></td>
+ <td width='1' style='background-color: rgba(183,178,73,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,88,1)'></td>
+ <td width='1' style='background-color: rgba(172,178,100,1)'></td>
+ <td width='1' style='background-color: rgba(166,178,111,1)'></td>
+ <td width='1' style='background-color: rgba(159,178,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,178,130,1)'></td>
+ <td width='1' style='background-color: rgba(145,178,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,178,145,1)'></td>
+ <td width='1' style='background-color: rgba(130,178,152,1)'></td>
+ <td width='1' style='background-color: rgba(121,178,159,1)'></td>
+ <td width='1' style='background-color: rgba(111,178,166,1)'></td>
+ <td width='1' style='background-color: rgba(100,178,172,1)'></td>
+ <td width='1' style='background-color: rgba(88,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(73,178,183,1)'></td>
+ <td width='1' style='background-color: rgba(53,178,189,1)'></td>
+ <td width='1' style='background-color: rgba(0,178,194,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,172,53,1)'></td>
+ <td width='1' style='background-color: rgba(189,172,73,1)'></td>
+ <td width='1' style='background-color: rgba(183,172,88,1)'></td>
+ <td width='1' style='background-color: rgba(178,172,100,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,111,1)'></td>
+ <td width='1' style='background-color: rgba(166,172,121,1)'></td>
+ <td width='1' style='background-color: rgba(159,172,130,1)'></td>
+ <td width='1' style='background-color: rgba(152,172,138,1)'></td>
+ <td width='1' style='background-color: rgba(145,172,145,1)'></td>
+ <td width='1' style='background-color: rgba(138,172,152,1)'></td>
+ <td width='1' style='background-color: rgba(130,172,159,1)'></td>
+ <td width='1' style='background-color: rgba(121,172,166,1)'></td>
+ <td width='1' style='background-color: rgba(111,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(100,172,178,1)'></td>
+ <td width='1' style='background-color: rgba(88,172,183,1)'></td>
+ <td width='1' style='background-color: rgba(73,172,189,1)'></td>
+ <td width='1' style='background-color: rgba(53,172,194,1)'></td>
+ <td width='1' style='background-color: rgba(0,172,199,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,166,53,1)'></td>
+ <td width='1' style='background-color: rgba(194,166,73,1)'></td>
+ <td width='1' style='background-color: rgba(189,166,88,1)'></td>
+ <td width='1' style='background-color: rgba(183,166,100,1)'></td>
+ <td width='1' style='background-color: rgba(178,166,111,1)'></td>
+ <td width='1' style='background-color: rgba(172,166,121,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,130,1)'></td>
+ <td width='1' style='background-color: rgba(159,166,138,1)'></td>
+ <td width='1' style='background-color: rgba(152,166,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,166,152,1)'></td>
+ <td width='1' style='background-color: rgba(138,166,159,1)'></td>
+ <td width='1' style='background-color: rgba(130,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(121,166,172,1)'></td>
+ <td width='1' style='background-color: rgba(111,166,178,1)'></td>
+ <td width='1' style='background-color: rgba(100,166,183,1)'></td>
+ <td width='1' style='background-color: rgba(88,166,189,1)'></td>
+ <td width='1' style='background-color: rgba(73,166,194,1)'></td>
+ <td width='1' style='background-color: rgba(53,166,199,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,204,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,159,53,1)'></td>
+ <td width='1' style='background-color: rgba(199,159,73,1)'></td>
+ <td width='1' style='background-color: rgba(194,159,88,1)'></td>
+ <td width='1' style='background-color: rgba(189,159,100,1)'></td>
+ <td width='1' style='background-color: rgba(183,159,111,1)'></td>
+ <td width='1' style='background-color: rgba(178,159,121,1)'></td>
+ <td width='1' style='background-color: rgba(172,159,130,1)'></td>
+ <td width='1' style='background-color: rgba(166,159,138,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,145,1)'></td>
+ <td width='1' style='background-color: rgba(152,159,152,1)'></td>
+ <td width='1' style='background-color: rgba(145,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(138,159,166,1)'></td>
+ <td width='1' style='background-color: rgba(130,159,172,1)'></td>
+ <td width='1' style='background-color: rgba(121,159,178,1)'></td>
+ <td width='1' style='background-color: rgba(111,159,183,1)'></td>
+ <td width='1' style='background-color: rgba(100,159,189,1)'></td>
+ <td width='1' style='background-color: rgba(88,159,194,1)'></td>
+ <td width='1' style='background-color: rgba(73,159,199,1)'></td>
+ <td width='1' style='background-color: rgba(53,159,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,159,209,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,152,53,1)'></td>
+ <td width='1' style='background-color: rgba(204,152,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,152,88,1)'></td>
+ <td width='1' style='background-color: rgba(194,152,100,1)'></td>
+ <td width='1' style='background-color: rgba(189,152,111,1)'></td>
+ <td width='1' style='background-color: rgba(183,152,121,1)'></td>
+ <td width='1' style='background-color: rgba(178,152,130,1)'></td>
+ <td width='1' style='background-color: rgba(172,152,138,1)'></td>
+ <td width='1' style='background-color: rgba(166,152,145,1)'></td>
+ <td width='1' style='background-color: rgba(159,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,159,1)'></td>
+ <td width='1' style='background-color: rgba(145,152,166,1)'></td>
+ <td width='1' style='background-color: rgba(138,152,172,1)'></td>
+ <td width='1' style='background-color: rgba(130,152,178,1)'></td>
+ <td width='1' style='background-color: rgba(121,152,183,1)'></td>
+ <td width='1' style='background-color: rgba(111,152,189,1)'></td>
+ <td width='1' style='background-color: rgba(100,152,194,1)'></td>
+ <td width='1' style='background-color: rgba(88,152,199,1)'></td>
+ <td width='1' style='background-color: rgba(73,152,204,1)'></td>
+ <td width='1' style='background-color: rgba(53,152,209,1)'></td>
+ <td width='1' style='background-color: rgba(0,152,214,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,145,53,1)'></td>
+ <td width='1' style='background-color: rgba(209,145,73,1)'></td>
+ <td width='1' style='background-color: rgba(204,145,88,1)'></td>
+ <td width='1' style='background-color: rgba(199,145,100,1)'></td>
+ <td width='1' style='background-color: rgba(194,145,111,1)'></td>
+ <td width='1' style='background-color: rgba(189,145,121,1)'></td>
+ <td width='1' style='background-color: rgba(183,145,130,1)'></td>
+ <td width='1' style='background-color: rgba(178,145,138,1)'></td>
+ <td width='1' style='background-color: rgba(172,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(166,145,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,145,159,1)'></td>
+ <td width='1' style='background-color: rgba(152,145,166,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,172,1)'></td>
+ <td width='1' style='background-color: rgba(138,145,178,1)'></td>
+ <td width='1' style='background-color: rgba(130,145,183,1)'></td>
+ <td width='1' style='background-color: rgba(121,145,189,1)'></td>
+ <td width='1' style='background-color: rgba(111,145,194,1)'></td>
+ <td width='1' style='background-color: rgba(100,145,199,1)'></td>
+ <td width='1' style='background-color: rgba(88,145,204,1)'></td>
+ <td width='1' style='background-color: rgba(73,145,209,1)'></td>
+ <td width='1' style='background-color: rgba(53,145,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,218,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,138,53,1)'></td>
+ <td width='1' style='background-color: rgba(214,138,73,1)'></td>
+ <td width='1' style='background-color: rgba(209,138,88,1)'></td>
+ <td width='1' style='background-color: rgba(204,138,100,1)'></td>
+ <td width='1' style='background-color: rgba(199,138,111,1)'></td>
+ <td width='1' style='background-color: rgba(194,138,121,1)'></td>
+ <td width='1' style='background-color: rgba(189,138,130,1)'></td>
+ <td width='1' style='background-color: rgba(183,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(178,138,145,1)'></td>
+ <td width='1' style='background-color: rgba(172,138,152,1)'></td>
+ <td width='1' style='background-color: rgba(166,138,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,138,166,1)'></td>
+ <td width='1' style='background-color: rgba(152,138,172,1)'></td>
+ <td width='1' style='background-color: rgba(145,138,178,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,183,1)'></td>
+ <td width='1' style='background-color: rgba(130,138,189,1)'></td>
+ <td width='1' style='background-color: rgba(121,138,194,1)'></td>
+ <td width='1' style='background-color: rgba(111,138,199,1)'></td>
+ <td width='1' style='background-color: rgba(100,138,204,1)'></td>
+ <td width='1' style='background-color: rgba(88,138,209,1)'></td>
+ <td width='1' style='background-color: rgba(73,138,214,1)'></td>
+ <td width='1' style='background-color: rgba(53,138,218,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,130,53,1)'></td>
+ <td width='1' style='background-color: rgba(218,130,73,1)'></td>
+ <td width='1' style='background-color: rgba(214,130,88,1)'></td>
+ <td width='1' style='background-color: rgba(209,130,100,1)'></td>
+ <td width='1' style='background-color: rgba(204,130,111,1)'></td>
+ <td width='1' style='background-color: rgba(199,130,121,1)'></td>
+ <td width='1' style='background-color: rgba(194,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(189,130,138,1)'></td>
+ <td width='1' style='background-color: rgba(183,130,145,1)'></td>
+ <td width='1' style='background-color: rgba(178,130,152,1)'></td>
+ <td width='1' style='background-color: rgba(172,130,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,130,166,1)'></td>
+ <td width='1' style='background-color: rgba(159,130,172,1)'></td>
+ <td width='1' style='background-color: rgba(152,130,178,1)'></td>
+ <td width='1' style='background-color: rgba(145,130,183,1)'></td>
+ <td width='1' style='background-color: rgba(138,130,189,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,194,1)'></td>
+ <td width='1' style='background-color: rgba(121,130,199,1)'></td>
+ <td width='1' style='background-color: rgba(111,130,204,1)'></td>
+ <td width='1' style='background-color: rgba(100,130,209,1)'></td>
+ <td width='1' style='background-color: rgba(88,130,214,1)'></td>
+ <td width='1' style='background-color: rgba(73,130,218,1)'></td>
+ <td width='1' style='background-color: rgba(53,130,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,130,227,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,121,53,1)'></td>
+ <td width='1' style='background-color: rgba(223,121,73,1)'></td>
+ <td width='1' style='background-color: rgba(218,121,88,1)'></td>
+ <td width='1' style='background-color: rgba(214,121,100,1)'></td>
+ <td width='1' style='background-color: rgba(209,121,111,1)'></td>
+ <td width='1' style='background-color: rgba(204,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(199,121,130,1)'></td>
+ <td width='1' style='background-color: rgba(194,121,138,1)'></td>
+ <td width='1' style='background-color: rgba(189,121,145,1)'></td>
+ <td width='1' style='background-color: rgba(183,121,152,1)'></td>
+ <td width='1' style='background-color: rgba(178,121,159,1)'></td>
+ <td width='1' style='background-color: rgba(172,121,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,121,172,1)'></td>
+ <td width='1' style='background-color: rgba(159,121,178,1)'></td>
+ <td width='1' style='background-color: rgba(152,121,183,1)'></td>
+ <td width='1' style='background-color: rgba(145,121,189,1)'></td>
+ <td width='1' style='background-color: rgba(138,121,194,1)'></td>
+ <td width='1' style='background-color: rgba(130,121,199,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,204,1)'></td>
+ <td width='1' style='background-color: rgba(111,121,209,1)'></td>
+ <td width='1' style='background-color: rgba(100,121,214,1)'></td>
+ <td width='1' style='background-color: rgba(88,121,218,1)'></td>
+ <td width='1' style='background-color: rgba(73,121,223,1)'></td>
+ <td width='1' style='background-color: rgba(53,121,227,1)'></td>
+ <td width='1' style='background-color: rgba(0,121,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,111,53,1)'></td>
+ <td width='1' style='background-color: rgba(227,111,73,1)'></td>
+ <td width='1' style='background-color: rgba(223,111,88,1)'></td>
+ <td width='1' style='background-color: rgba(218,111,100,1)'></td>
+ <td width='1' style='background-color: rgba(214,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(209,111,121,1)'></td>
+ <td width='1' style='background-color: rgba(204,111,130,1)'></td>
+ <td width='1' style='background-color: rgba(199,111,138,1)'></td>
+ <td width='1' style='background-color: rgba(194,111,145,1)'></td>
+ <td width='1' style='background-color: rgba(189,111,152,1)'></td>
+ <td width='1' style='background-color: rgba(183,111,159,1)'></td>
+ <td width='1' style='background-color: rgba(178,111,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,111,172,1)'></td>
+ <td width='1' style='background-color: rgba(166,111,178,1)'></td>
+ <td width='1' style='background-color: rgba(159,111,183,1)'></td>
+ <td width='1' style='background-color: rgba(152,111,189,1)'></td>
+ <td width='1' style='background-color: rgba(145,111,194,1)'></td>
+ <td width='1' style='background-color: rgba(138,111,199,1)'></td>
+ <td width='1' style='background-color: rgba(130,111,204,1)'></td>
+ <td width='1' style='background-color: rgba(121,111,209,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,214,1)'></td>
+ <td width='1' style='background-color: rgba(100,111,218,1)'></td>
+ <td width='1' style='background-color: rgba(88,111,223,1)'></td>
+ <td width='1' style='background-color: rgba(73,111,227,1)'></td>
+ <td width='1' style='background-color: rgba(53,111,231,1)'></td>
+ <td width='1' style='background-color: rgba(0,111,235,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,100,53,1)'></td>
+ <td width='1' style='background-color: rgba(231,100,73,1)'></td>
+ <td width='1' style='background-color: rgba(227,100,88,1)'></td>
+ <td width='1' style='background-color: rgba(223,100,100,1)'></td>
+ <td width='1' style='background-color: rgba(218,100,111,1)'></td>
+ <td width='1' style='background-color: rgba(214,100,121,1)'></td>
+ <td width='1' style='background-color: rgba(209,100,130,1)'></td>
+ <td width='1' style='background-color: rgba(204,100,138,1)'></td>
+ <td width='1' style='background-color: rgba(199,100,145,1)'></td>
+ <td width='1' style='background-color: rgba(194,100,152,1)'></td>
+ <td width='1' style='background-color: rgba(189,100,159,1)'></td>
+ <td width='1' style='background-color: rgba(183,100,166,1)'></td>
+ <td width='1' style='background-color: rgba(178,100,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,100,178,1)'></td>
+ <td width='1' style='background-color: rgba(166,100,183,1)'></td>
+ <td width='1' style='background-color: rgba(159,100,189,1)'></td>
+ <td width='1' style='background-color: rgba(152,100,194,1)'></td>
+ <td width='1' style='background-color: rgba(145,100,199,1)'></td>
+ <td width='1' style='background-color: rgba(138,100,204,1)'></td>
+ <td width='1' style='background-color: rgba(130,100,209,1)'></td>
+ <td width='1' style='background-color: rgba(121,100,214,1)'></td>
+ <td width='1' style='background-color: rgba(111,100,218,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,223,1)'></td>
+ <td width='1' style='background-color: rgba(88,100,227,1)'></td>
+ <td width='1' style='background-color: rgba(73,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(53,100,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,100,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,88,53,1)'></td>
+ <td width='1' style='background-color: rgba(235,88,73,1)'></td>
+ <td width='1' style='background-color: rgba(231,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(227,88,100,1)'></td>
+ <td width='1' style='background-color: rgba(223,88,111,1)'></td>
+ <td width='1' style='background-color: rgba(218,88,121,1)'></td>
+ <td width='1' style='background-color: rgba(214,88,130,1)'></td>
+ <td width='1' style='background-color: rgba(209,88,138,1)'></td>
+ <td width='1' style='background-color: rgba(204,88,145,1)'></td>
+ <td width='1' style='background-color: rgba(199,88,152,1)'></td>
+ <td width='1' style='background-color: rgba(194,88,159,1)'></td>
+ <td width='1' style='background-color: rgba(189,88,166,1)'></td>
+ <td width='1' style='background-color: rgba(183,88,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,88,178,1)'></td>
+ <td width='1' style='background-color: rgba(172,88,183,1)'></td>
+ <td width='1' style='background-color: rgba(166,88,189,1)'></td>
+ <td width='1' style='background-color: rgba(159,88,194,1)'></td>
+ <td width='1' style='background-color: rgba(152,88,199,1)'></td>
+ <td width='1' style='background-color: rgba(145,88,204,1)'></td>
+ <td width='1' style='background-color: rgba(138,88,209,1)'></td>
+ <td width='1' style='background-color: rgba(130,88,214,1)'></td>
+ <td width='1' style='background-color: rgba(121,88,218,1)'></td>
+ <td width='1' style='background-color: rgba(111,88,223,1)'></td>
+ <td width='1' style='background-color: rgba(100,88,227,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,231,1)'></td>
+ <td width='1' style='background-color: rgba(73,88,235,1)'></td>
+ <td width='1' style='background-color: rgba(53,88,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,243,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,73,53,1)'></td>
+ <td width='1' style='background-color: rgba(239,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(235,73,88,1)'></td>
+ <td width='1' style='background-color: rgba(231,73,100,1)'></td>
+ <td width='1' style='background-color: rgba(227,73,111,1)'></td>
+ <td width='1' style='background-color: rgba(223,73,121,1)'></td>
+ <td width='1' style='background-color: rgba(218,73,130,1)'></td>
+ <td width='1' style='background-color: rgba(214,73,138,1)'></td>
+ <td width='1' style='background-color: rgba(209,73,145,1)'></td>
+ <td width='1' style='background-color: rgba(204,73,152,1)'></td>
+ <td width='1' style='background-color: rgba(199,73,159,1)'></td>
+ <td width='1' style='background-color: rgba(194,73,166,1)'></td>
+ <td width='1' style='background-color: rgba(189,73,172,1)'></td>
+ <td width='1' style='background-color: rgba(183,73,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,73,183,1)'></td>
+ <td width='1' style='background-color: rgba(172,73,189,1)'></td>
+ <td width='1' style='background-color: rgba(166,73,194,1)'></td>
+ <td width='1' style='background-color: rgba(159,73,199,1)'></td>
+ <td width='1' style='background-color: rgba(152,73,204,1)'></td>
+ <td width='1' style='background-color: rgba(145,73,209,1)'></td>
+ <td width='1' style='background-color: rgba(138,73,214,1)'></td>
+ <td width='1' style='background-color: rgba(130,73,218,1)'></td>
+ <td width='1' style='background-color: rgba(121,73,223,1)'></td>
+ <td width='1' style='background-color: rgba(111,73,227,1)'></td>
+ <td width='1' style='background-color: rgba(100,73,231,1)'></td>
+ <td width='1' style='background-color: rgba(88,73,235,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,239,1)'></td>
+ <td width='1' style='background-color: rgba(53,73,243,1)'></td>
+ <td width='1' style='background-color: rgba(0,73,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,53,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,53,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(243,53,73,1)'></td>
+ <td width='1' style='background-color: rgba(239,53,88,1)'></td>
+ <td width='1' style='background-color: rgba(235,53,100,1)'></td>
+ <td width='1' style='background-color: rgba(231,53,111,1)'></td>
+ <td width='1' style='background-color: rgba(227,53,121,1)'></td>
+ <td width='1' style='background-color: rgba(223,53,130,1)'></td>
+ <td width='1' style='background-color: rgba(218,53,138,1)'></td>
+ <td width='1' style='background-color: rgba(214,53,145,1)'></td>
+ <td width='1' style='background-color: rgba(209,53,152,1)'></td>
+ <td width='1' style='background-color: rgba(204,53,159,1)'></td>
+ <td width='1' style='background-color: rgba(199,53,166,1)'></td>
+ <td width='1' style='background-color: rgba(194,53,172,1)'></td>
+ <td width='1' style='background-color: rgba(189,53,178,1)'></td>
+ <td width='1' style='background-color: rgba(183,53,183,1)'></td>
+ <td width='1' style='background-color: rgba(178,53,189,1)'></td>
+ <td width='1' style='background-color: rgba(172,53,194,1)'></td>
+ <td width='1' style='background-color: rgba(166,53,199,1)'></td>
+ <td width='1' style='background-color: rgba(159,53,204,1)'></td>
+ <td width='1' style='background-color: rgba(152,53,209,1)'></td>
+ <td width='1' style='background-color: rgba(145,53,214,1)'></td>
+ <td width='1' style='background-color: rgba(138,53,218,1)'></td>
+ <td width='1' style='background-color: rgba(130,53,223,1)'></td>
+ <td width='1' style='background-color: rgba(121,53,227,1)'></td>
+ <td width='1' style='background-color: rgba(111,53,231,1)'></td>
+ <td width='1' style='background-color: rgba(100,53,235,1)'></td>
+ <td width='1' style='background-color: rgba(88,53,239,1)'></td>
+ <td width='1' style='background-color: rgba(73,53,243,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,251,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,53,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,73,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,88,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,100,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,111,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,121,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,130,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,138,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,145,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,152,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,159,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,166,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,172,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,178,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,189,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,194,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,199,1)'></td>
+ <td width='1' style='background-color: rgba(166,0,204,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,209,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,214,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,218,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,223,1)'></td>
+ <td width='1' style='background-color: rgba(130,0,227,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,231,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,235,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,239,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,243,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,251,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-palettes/ps1n2c16.png b/image/test/reftest/pngsuite-palettes/ps1n2c16.png
new file mode 100644
index 0000000000..b03ecfc669
--- /dev/null
+++ b/image/test/reftest/pngsuite-palettes/ps1n2c16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-palettes/ps2n0g08.html b/image/test/reftest/pngsuite-palettes/ps2n0g08.html
new file mode 100644
index 0000000000..5aaf11cabb
--- /dev/null
+++ b/image/test/reftest/pngsuite-palettes/ps2n0g08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(255,255,255,1)'></td>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(254,254,254,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(253,253,253,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(252,252,252,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,251,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(250,250,250,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(249,249,249,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(248,248,248,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,247,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(246,246,246,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(245,245,245,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(244,244,244,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,243,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(242,242,242,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(241,241,241,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(240,240,240,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(238,238,238,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(237,237,237,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(236,236,236,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,235,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(234,234,234,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(233,233,233,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(232,232,232,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,231,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,230,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(229,229,229,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(228,228,228,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,227,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(226,226,226,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(225,225,225,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(224,224,224,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(222,222,222,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(221,221,221,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(220,220,220,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(219,219,219,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,218,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(217,217,217,1)'></td>
+ <td width='1' style='background-color: rgba(216,216,216,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(215,215,215,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,214,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(213,213,213,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(212,212,212,1)'></td>
+ <td width='1' style='background-color: rgba(211,211,211,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(210,210,210,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,209,1)'></td>
+ <td width='1' style='background-color: rgba(208,208,208,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(207,207,207,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,206,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+ <td width='1' style='background-color: rgba(205,205,205,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(204,204,204,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(203,203,203,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(202,202,202,1)'></td>
+ <td width='1' style='background-color: rgba(201,201,201,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(200,200,200,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,199,1)'></td>
+ <td width='1' style='background-color: rgba(198,198,198,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,197,1)'></td>
+ <td width='1' style='background-color: rgba(196,196,196,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(195,195,195,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,194,1)'></td>
+ <td width='1' style='background-color: rgba(193,193,193,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(192,192,192,1)'></td>
+ <td width='1' style='background-color: rgba(191,191,191,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(190,190,190,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,189,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(188,188,188,1)'></td>
+ <td width='1' style='background-color: rgba(187,187,187,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(186,186,186,1)'></td>
+ <td width='1' style='background-color: rgba(185,185,185,1)'></td>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(184,184,184,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(182,182,182,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,181,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(180,180,180,1)'></td>
+ <td width='1' style='background-color: rgba(179,179,179,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(177,177,177,1)'></td>
+ <td width='1' style='background-color: rgba(176,176,176,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(175,175,175,1)'></td>
+ <td width='1' style='background-color: rgba(174,174,174,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,173,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(171,171,171,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(170,170,170,1)'></td>
+ <td width='1' style='background-color: rgba(169,169,169,1)'></td>
+ <td width='1' style='background-color: rgba(168,168,168,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(167,167,167,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,165,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(164,164,164,1)'></td>
+ <td width='1' style='background-color: rgba(163,163,163,1)'></td>
+ <td width='1' style='background-color: rgba(162,162,162,1)'></td>
+ <td width='1' style='background-color: rgba(161,161,161,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(160,160,160,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(158,158,158,1)'></td>
+ <td width='1' style='background-color: rgba(157,157,157,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,156,1)'></td>
+ <td width='1' style='background-color: rgba(155,155,155,1)'></td>
+ <td width='1' style='background-color: rgba(154,154,154,1)'></td>
+ <td width='1' style='background-color: rgba(153,153,153,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(151,151,151,1)'></td>
+ <td width='1' style='background-color: rgba(150,150,150,1)'></td>
+ <td width='1' style='background-color: rgba(149,149,149,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,148,1)'></td>
+ <td width='1' style='background-color: rgba(147,147,147,1)'></td>
+ <td width='1' style='background-color: rgba(146,146,146,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(144,144,144,1)'></td>
+ <td width='1' style='background-color: rgba(143,143,143,1)'></td>
+ <td width='1' style='background-color: rgba(142,142,142,1)'></td>
+ <td width='1' style='background-color: rgba(141,141,141,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,140,1)'></td>
+ <td width='1' style='background-color: rgba(139,139,139,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(137,137,137,1)'></td>
+ <td width='1' style='background-color: rgba(136,136,136,1)'></td>
+ <td width='1' style='background-color: rgba(135,135,135,1)'></td>
+ <td width='1' style='background-color: rgba(134,134,134,1)'></td>
+ <td width='1' style='background-color: rgba(133,133,133,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(132,132,132,1)'></td>
+ <td width='1' style='background-color: rgba(131,131,131,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(129,129,129,1)'></td>
+ <td width='1' style='background-color: rgba(128,128,128,1)'></td>
+ <td width='1' style='background-color: rgba(127,127,127,1)'></td>
+ <td width='1' style='background-color: rgba(126,126,126,1)'></td>
+ <td width='1' style='background-color: rgba(125,125,125,1)'></td>
+ <td width='1' style='background-color: rgba(124,124,124,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(122,122,122,1)'></td>
+ <td width='1' style='background-color: rgba(120,120,120,1)'></td>
+ <td width='1' style='background-color: rgba(119,119,119,1)'></td>
+ <td width='1' style='background-color: rgba(118,118,118,1)'></td>
+ <td width='1' style='background-color: rgba(117,117,117,1)'></td>
+ <td width='1' style='background-color: rgba(116,116,116,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(114,114,114,1)'></td>
+ <td width='1' style='background-color: rgba(112,112,112,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(110,110,110,1)'></td>
+ <td width='1' style='background-color: rgba(109,109,109,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(106,106,106,1)'></td>
+ <td width='1' style='background-color: rgba(105,105,105,1)'></td>
+ <td width='1' style='background-color: rgba(103,103,103,1)'></td>
+ <td width='1' style='background-color: rgba(102,102,102,1)'></td>
+ <td width='1' style='background-color: rgba(101,101,101,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(98,98,98,1)'></td>
+ <td width='1' style='background-color: rgba(96,96,96,1)'></td>
+ <td width='1' style='background-color: rgba(95,95,95,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(93,93,93,1)'></td>
+ <td width='1' style='background-color: rgba(92,92,92,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(89,89,89,1)'></td>
+ <td width='1' style='background-color: rgba(87,87,87,1)'></td>
+ <td width='1' style='background-color: rgba(85,85,85,1)'></td>
+ <td width='1' style='background-color: rgba(84,84,84,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(80,80,80,1)'></td>
+ <td width='1' style='background-color: rgba(78,78,78,1)'></td>
+ <td width='1' style='background-color: rgba(76,76,76,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(72,72,72,1)'></td>
+ <td width='1' style='background-color: rgba(70,70,70,1)'></td>
+ <td width='1' style='background-color: rgba(68,68,68,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(64,64,64,1)'></td>
+ <td width='1' style='background-color: rgba(61,61,61,1)'></td>
+ <td width='1' style='background-color: rgba(59,59,59,1)'></td>
+ <td width='1' style='background-color: rgba(56,56,56,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(50,50,50,1)'></td>
+ <td width='1' style='background-color: rgba(46,46,46,1)'></td>
+ <td width='1' style='background-color: rgba(43,43,43,1)'></td>
+ <td width='1' style='background-color: rgba(39,39,39,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(21,21,21,1)'></td>
+ <td width='1' style='background-color: rgba(28,28,28,1)'></td>
+ <td width='1' style='background-color: rgba(34,34,34,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-palettes/ps2n0g08.png b/image/test/reftest/pngsuite-palettes/ps2n0g08.png
new file mode 100644
index 0000000000..beeab8ff3d
--- /dev/null
+++ b/image/test/reftest/pngsuite-palettes/ps2n0g08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-palettes/ps2n2c16.html b/image/test/reftest/pngsuite-palettes/ps2n2c16.html
new file mode 100644
index 0000000000..dd08f0e3d0
--- /dev/null
+++ b/image/test/reftest/pngsuite-palettes/ps2n2c16.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,251,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,251,53,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(53,247,53,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,73,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,243,0,1)'></td>
+ <td width='1' style='background-color: rgba(73,243,53,1)'></td>
+ <td width='1' style='background-color: rgba(53,243,73,1)'></td>
+ <td width='1' style='background-color: rgba(0,243,88,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(88,239,53,1)'></td>
+ <td width='1' style='background-color: rgba(73,239,73,1)'></td>
+ <td width='1' style='background-color: rgba(53,239,88,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,100,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,235,0,1)'></td>
+ <td width='1' style='background-color: rgba(100,235,53,1)'></td>
+ <td width='1' style='background-color: rgba(88,235,73,1)'></td>
+ <td width='1' style='background-color: rgba(73,235,88,1)'></td>
+ <td width='1' style='background-color: rgba(53,235,100,1)'></td>
+ <td width='1' style='background-color: rgba(0,235,111,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,231,0,1)'></td>
+ <td width='1' style='background-color: rgba(111,231,53,1)'></td>
+ <td width='1' style='background-color: rgba(100,231,73,1)'></td>
+ <td width='1' style='background-color: rgba(88,231,88,1)'></td>
+ <td width='1' style='background-color: rgba(73,231,100,1)'></td>
+ <td width='1' style='background-color: rgba(53,231,111,1)'></td>
+ <td width='1' style='background-color: rgba(0,231,121,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,227,0,1)'></td>
+ <td width='1' style='background-color: rgba(121,227,53,1)'></td>
+ <td width='1' style='background-color: rgba(111,227,73,1)'></td>
+ <td width='1' style='background-color: rgba(100,227,88,1)'></td>
+ <td width='1' style='background-color: rgba(88,227,100,1)'></td>
+ <td width='1' style='background-color: rgba(73,227,111,1)'></td>
+ <td width='1' style='background-color: rgba(53,227,121,1)'></td>
+ <td width='1' style='background-color: rgba(0,227,130,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,223,0,1)'></td>
+ <td width='1' style='background-color: rgba(130,223,53,1)'></td>
+ <td width='1' style='background-color: rgba(121,223,73,1)'></td>
+ <td width='1' style='background-color: rgba(111,223,88,1)'></td>
+ <td width='1' style='background-color: rgba(100,223,100,1)'></td>
+ <td width='1' style='background-color: rgba(88,223,111,1)'></td>
+ <td width='1' style='background-color: rgba(73,223,121,1)'></td>
+ <td width='1' style='background-color: rgba(53,223,130,1)'></td>
+ <td width='1' style='background-color: rgba(0,223,138,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,218,0,1)'></td>
+ <td width='1' style='background-color: rgba(138,218,53,1)'></td>
+ <td width='1' style='background-color: rgba(130,218,73,1)'></td>
+ <td width='1' style='background-color: rgba(121,218,88,1)'></td>
+ <td width='1' style='background-color: rgba(111,218,100,1)'></td>
+ <td width='1' style='background-color: rgba(100,218,111,1)'></td>
+ <td width='1' style='background-color: rgba(88,218,121,1)'></td>
+ <td width='1' style='background-color: rgba(73,218,130,1)'></td>
+ <td width='1' style='background-color: rgba(53,218,138,1)'></td>
+ <td width='1' style='background-color: rgba(0,218,145,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(145,214,53,1)'></td>
+ <td width='1' style='background-color: rgba(138,214,73,1)'></td>
+ <td width='1' style='background-color: rgba(130,214,88,1)'></td>
+ <td width='1' style='background-color: rgba(121,214,100,1)'></td>
+ <td width='1' style='background-color: rgba(111,214,111,1)'></td>
+ <td width='1' style='background-color: rgba(100,214,121,1)'></td>
+ <td width='1' style='background-color: rgba(88,214,130,1)'></td>
+ <td width='1' style='background-color: rgba(73,214,138,1)'></td>
+ <td width='1' style='background-color: rgba(53,214,145,1)'></td>
+ <td width='1' style='background-color: rgba(0,214,152,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,209,0,1)'></td>
+ <td width='1' style='background-color: rgba(152,209,53,1)'></td>
+ <td width='1' style='background-color: rgba(145,209,73,1)'></td>
+ <td width='1' style='background-color: rgba(138,209,88,1)'></td>
+ <td width='1' style='background-color: rgba(130,209,100,1)'></td>
+ <td width='1' style='background-color: rgba(121,209,111,1)'></td>
+ <td width='1' style='background-color: rgba(111,209,121,1)'></td>
+ <td width='1' style='background-color: rgba(100,209,130,1)'></td>
+ <td width='1' style='background-color: rgba(88,209,138,1)'></td>
+ <td width='1' style='background-color: rgba(73,209,145,1)'></td>
+ <td width='1' style='background-color: rgba(53,209,152,1)'></td>
+ <td width='1' style='background-color: rgba(0,209,159,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,204,0,1)'></td>
+ <td width='1' style='background-color: rgba(159,204,53,1)'></td>
+ <td width='1' style='background-color: rgba(152,204,73,1)'></td>
+ <td width='1' style='background-color: rgba(145,204,88,1)'></td>
+ <td width='1' style='background-color: rgba(138,204,100,1)'></td>
+ <td width='1' style='background-color: rgba(130,204,111,1)'></td>
+ <td width='1' style='background-color: rgba(121,204,121,1)'></td>
+ <td width='1' style='background-color: rgba(111,204,130,1)'></td>
+ <td width='1' style='background-color: rgba(100,204,138,1)'></td>
+ <td width='1' style='background-color: rgba(88,204,145,1)'></td>
+ <td width='1' style='background-color: rgba(73,204,152,1)'></td>
+ <td width='1' style='background-color: rgba(53,204,159,1)'></td>
+ <td width='1' style='background-color: rgba(0,204,166,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,199,0,1)'></td>
+ <td width='1' style='background-color: rgba(166,199,53,1)'></td>
+ <td width='1' style='background-color: rgba(159,199,73,1)'></td>
+ <td width='1' style='background-color: rgba(152,199,88,1)'></td>
+ <td width='1' style='background-color: rgba(145,199,100,1)'></td>
+ <td width='1' style='background-color: rgba(138,199,111,1)'></td>
+ <td width='1' style='background-color: rgba(130,199,121,1)'></td>
+ <td width='1' style='background-color: rgba(121,199,130,1)'></td>
+ <td width='1' style='background-color: rgba(111,199,138,1)'></td>
+ <td width='1' style='background-color: rgba(100,199,145,1)'></td>
+ <td width='1' style='background-color: rgba(88,199,152,1)'></td>
+ <td width='1' style='background-color: rgba(73,199,159,1)'></td>
+ <td width='1' style='background-color: rgba(53,199,166,1)'></td>
+ <td width='1' style='background-color: rgba(0,199,172,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,194,0,1)'></td>
+ <td width='1' style='background-color: rgba(172,194,53,1)'></td>
+ <td width='1' style='background-color: rgba(166,194,73,1)'></td>
+ <td width='1' style='background-color: rgba(159,194,88,1)'></td>
+ <td width='1' style='background-color: rgba(152,194,100,1)'></td>
+ <td width='1' style='background-color: rgba(145,194,111,1)'></td>
+ <td width='1' style='background-color: rgba(138,194,121,1)'></td>
+ <td width='1' style='background-color: rgba(130,194,130,1)'></td>
+ <td width='1' style='background-color: rgba(121,194,138,1)'></td>
+ <td width='1' style='background-color: rgba(111,194,145,1)'></td>
+ <td width='1' style='background-color: rgba(100,194,152,1)'></td>
+ <td width='1' style='background-color: rgba(88,194,159,1)'></td>
+ <td width='1' style='background-color: rgba(73,194,166,1)'></td>
+ <td width='1' style='background-color: rgba(53,194,172,1)'></td>
+ <td width='1' style='background-color: rgba(0,194,178,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(178,189,53,1)'></td>
+ <td width='1' style='background-color: rgba(172,189,73,1)'></td>
+ <td width='1' style='background-color: rgba(166,189,88,1)'></td>
+ <td width='1' style='background-color: rgba(159,189,100,1)'></td>
+ <td width='1' style='background-color: rgba(152,189,111,1)'></td>
+ <td width='1' style='background-color: rgba(145,189,121,1)'></td>
+ <td width='1' style='background-color: rgba(138,189,130,1)'></td>
+ <td width='1' style='background-color: rgba(130,189,138,1)'></td>
+ <td width='1' style='background-color: rgba(121,189,145,1)'></td>
+ <td width='1' style='background-color: rgba(111,189,152,1)'></td>
+ <td width='1' style='background-color: rgba(100,189,159,1)'></td>
+ <td width='1' style='background-color: rgba(88,189,166,1)'></td>
+ <td width='1' style='background-color: rgba(73,189,172,1)'></td>
+ <td width='1' style='background-color: rgba(53,189,178,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,183,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,183,0,1)'></td>
+ <td width='1' style='background-color: rgba(183,183,53,1)'></td>
+ <td width='1' style='background-color: rgba(178,183,73,1)'></td>
+ <td width='1' style='background-color: rgba(172,183,88,1)'></td>
+ <td width='1' style='background-color: rgba(166,183,100,1)'></td>
+ <td width='1' style='background-color: rgba(159,183,111,1)'></td>
+ <td width='1' style='background-color: rgba(152,183,121,1)'></td>
+ <td width='1' style='background-color: rgba(145,183,130,1)'></td>
+ <td width='1' style='background-color: rgba(138,183,138,1)'></td>
+ <td width='1' style='background-color: rgba(130,183,145,1)'></td>
+ <td width='1' style='background-color: rgba(121,183,152,1)'></td>
+ <td width='1' style='background-color: rgba(111,183,159,1)'></td>
+ <td width='1' style='background-color: rgba(100,183,166,1)'></td>
+ <td width='1' style='background-color: rgba(88,183,172,1)'></td>
+ <td width='1' style='background-color: rgba(73,183,178,1)'></td>
+ <td width='1' style='background-color: rgba(53,183,183,1)'></td>
+ <td width='1' style='background-color: rgba(0,183,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,178,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,178,53,1)'></td>
+ <td width='1' style='background-color: rgba(183,178,73,1)'></td>
+ <td width='1' style='background-color: rgba(178,178,88,1)'></td>
+ <td width='1' style='background-color: rgba(172,178,100,1)'></td>
+ <td width='1' style='background-color: rgba(166,178,111,1)'></td>
+ <td width='1' style='background-color: rgba(159,178,121,1)'></td>
+ <td width='1' style='background-color: rgba(152,178,130,1)'></td>
+ <td width='1' style='background-color: rgba(145,178,138,1)'></td>
+ <td width='1' style='background-color: rgba(138,178,145,1)'></td>
+ <td width='1' style='background-color: rgba(130,178,152,1)'></td>
+ <td width='1' style='background-color: rgba(121,178,159,1)'></td>
+ <td width='1' style='background-color: rgba(111,178,166,1)'></td>
+ <td width='1' style='background-color: rgba(100,178,172,1)'></td>
+ <td width='1' style='background-color: rgba(88,178,178,1)'></td>
+ <td width='1' style='background-color: rgba(73,178,183,1)'></td>
+ <td width='1' style='background-color: rgba(53,178,189,1)'></td>
+ <td width='1' style='background-color: rgba(0,178,194,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,172,0,1)'></td>
+ <td width='1' style='background-color: rgba(194,172,53,1)'></td>
+ <td width='1' style='background-color: rgba(189,172,73,1)'></td>
+ <td width='1' style='background-color: rgba(183,172,88,1)'></td>
+ <td width='1' style='background-color: rgba(178,172,100,1)'></td>
+ <td width='1' style='background-color: rgba(172,172,111,1)'></td>
+ <td width='1' style='background-color: rgba(166,172,121,1)'></td>
+ <td width='1' style='background-color: rgba(159,172,130,1)'></td>
+ <td width='1' style='background-color: rgba(152,172,138,1)'></td>
+ <td width='1' style='background-color: rgba(145,172,145,1)'></td>
+ <td width='1' style='background-color: rgba(138,172,152,1)'></td>
+ <td width='1' style='background-color: rgba(130,172,159,1)'></td>
+ <td width='1' style='background-color: rgba(121,172,166,1)'></td>
+ <td width='1' style='background-color: rgba(111,172,172,1)'></td>
+ <td width='1' style='background-color: rgba(100,172,178,1)'></td>
+ <td width='1' style='background-color: rgba(88,172,183,1)'></td>
+ <td width='1' style='background-color: rgba(73,172,189,1)'></td>
+ <td width='1' style='background-color: rgba(53,172,194,1)'></td>
+ <td width='1' style='background-color: rgba(0,172,199,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,166,0,1)'></td>
+ <td width='1' style='background-color: rgba(199,166,53,1)'></td>
+ <td width='1' style='background-color: rgba(194,166,73,1)'></td>
+ <td width='1' style='background-color: rgba(189,166,88,1)'></td>
+ <td width='1' style='background-color: rgba(183,166,100,1)'></td>
+ <td width='1' style='background-color: rgba(178,166,111,1)'></td>
+ <td width='1' style='background-color: rgba(172,166,121,1)'></td>
+ <td width='1' style='background-color: rgba(166,166,130,1)'></td>
+ <td width='1' style='background-color: rgba(159,166,138,1)'></td>
+ <td width='1' style='background-color: rgba(152,166,145,1)'></td>
+ <td width='1' style='background-color: rgba(145,166,152,1)'></td>
+ <td width='1' style='background-color: rgba(138,166,159,1)'></td>
+ <td width='1' style='background-color: rgba(130,166,166,1)'></td>
+ <td width='1' style='background-color: rgba(121,166,172,1)'></td>
+ <td width='1' style='background-color: rgba(111,166,178,1)'></td>
+ <td width='1' style='background-color: rgba(100,166,183,1)'></td>
+ <td width='1' style='background-color: rgba(88,166,189,1)'></td>
+ <td width='1' style='background-color: rgba(73,166,194,1)'></td>
+ <td width='1' style='background-color: rgba(53,166,199,1)'></td>
+ <td width='1' style='background-color: rgba(0,166,204,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,159,0,1)'></td>
+ <td width='1' style='background-color: rgba(204,159,53,1)'></td>
+ <td width='1' style='background-color: rgba(199,159,73,1)'></td>
+ <td width='1' style='background-color: rgba(194,159,88,1)'></td>
+ <td width='1' style='background-color: rgba(189,159,100,1)'></td>
+ <td width='1' style='background-color: rgba(183,159,111,1)'></td>
+ <td width='1' style='background-color: rgba(178,159,121,1)'></td>
+ <td width='1' style='background-color: rgba(172,159,130,1)'></td>
+ <td width='1' style='background-color: rgba(166,159,138,1)'></td>
+ <td width='1' style='background-color: rgba(159,159,145,1)'></td>
+ <td width='1' style='background-color: rgba(152,159,152,1)'></td>
+ <td width='1' style='background-color: rgba(145,159,159,1)'></td>
+ <td width='1' style='background-color: rgba(138,159,166,1)'></td>
+ <td width='1' style='background-color: rgba(130,159,172,1)'></td>
+ <td width='1' style='background-color: rgba(121,159,178,1)'></td>
+ <td width='1' style='background-color: rgba(111,159,183,1)'></td>
+ <td width='1' style='background-color: rgba(100,159,189,1)'></td>
+ <td width='1' style='background-color: rgba(88,159,194,1)'></td>
+ <td width='1' style='background-color: rgba(73,159,199,1)'></td>
+ <td width='1' style='background-color: rgba(53,159,204,1)'></td>
+ <td width='1' style='background-color: rgba(0,159,209,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,152,0,1)'></td>
+ <td width='1' style='background-color: rgba(209,152,53,1)'></td>
+ <td width='1' style='background-color: rgba(204,152,73,1)'></td>
+ <td width='1' style='background-color: rgba(199,152,88,1)'></td>
+ <td width='1' style='background-color: rgba(194,152,100,1)'></td>
+ <td width='1' style='background-color: rgba(189,152,111,1)'></td>
+ <td width='1' style='background-color: rgba(183,152,121,1)'></td>
+ <td width='1' style='background-color: rgba(178,152,130,1)'></td>
+ <td width='1' style='background-color: rgba(172,152,138,1)'></td>
+ <td width='1' style='background-color: rgba(166,152,145,1)'></td>
+ <td width='1' style='background-color: rgba(159,152,152,1)'></td>
+ <td width='1' style='background-color: rgba(152,152,159,1)'></td>
+ <td width='1' style='background-color: rgba(145,152,166,1)'></td>
+ <td width='1' style='background-color: rgba(138,152,172,1)'></td>
+ <td width='1' style='background-color: rgba(130,152,178,1)'></td>
+ <td width='1' style='background-color: rgba(121,152,183,1)'></td>
+ <td width='1' style='background-color: rgba(111,152,189,1)'></td>
+ <td width='1' style='background-color: rgba(100,152,194,1)'></td>
+ <td width='1' style='background-color: rgba(88,152,199,1)'></td>
+ <td width='1' style='background-color: rgba(73,152,204,1)'></td>
+ <td width='1' style='background-color: rgba(53,152,209,1)'></td>
+ <td width='1' style='background-color: rgba(0,152,214,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,145,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,145,53,1)'></td>
+ <td width='1' style='background-color: rgba(209,145,73,1)'></td>
+ <td width='1' style='background-color: rgba(204,145,88,1)'></td>
+ <td width='1' style='background-color: rgba(199,145,100,1)'></td>
+ <td width='1' style='background-color: rgba(194,145,111,1)'></td>
+ <td width='1' style='background-color: rgba(189,145,121,1)'></td>
+ <td width='1' style='background-color: rgba(183,145,130,1)'></td>
+ <td width='1' style='background-color: rgba(178,145,138,1)'></td>
+ <td width='1' style='background-color: rgba(172,145,145,1)'></td>
+ <td width='1' style='background-color: rgba(166,145,152,1)'></td>
+ <td width='1' style='background-color: rgba(159,145,159,1)'></td>
+ <td width='1' style='background-color: rgba(152,145,166,1)'></td>
+ <td width='1' style='background-color: rgba(145,145,172,1)'></td>
+ <td width='1' style='background-color: rgba(138,145,178,1)'></td>
+ <td width='1' style='background-color: rgba(130,145,183,1)'></td>
+ <td width='1' style='background-color: rgba(121,145,189,1)'></td>
+ <td width='1' style='background-color: rgba(111,145,194,1)'></td>
+ <td width='1' style='background-color: rgba(100,145,199,1)'></td>
+ <td width='1' style='background-color: rgba(88,145,204,1)'></td>
+ <td width='1' style='background-color: rgba(73,145,209,1)'></td>
+ <td width='1' style='background-color: rgba(53,145,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,145,218,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,138,0,1)'></td>
+ <td width='1' style='background-color: rgba(218,138,53,1)'></td>
+ <td width='1' style='background-color: rgba(214,138,73,1)'></td>
+ <td width='1' style='background-color: rgba(209,138,88,1)'></td>
+ <td width='1' style='background-color: rgba(204,138,100,1)'></td>
+ <td width='1' style='background-color: rgba(199,138,111,1)'></td>
+ <td width='1' style='background-color: rgba(194,138,121,1)'></td>
+ <td width='1' style='background-color: rgba(189,138,130,1)'></td>
+ <td width='1' style='background-color: rgba(183,138,138,1)'></td>
+ <td width='1' style='background-color: rgba(178,138,145,1)'></td>
+ <td width='1' style='background-color: rgba(172,138,152,1)'></td>
+ <td width='1' style='background-color: rgba(166,138,159,1)'></td>
+ <td width='1' style='background-color: rgba(159,138,166,1)'></td>
+ <td width='1' style='background-color: rgba(152,138,172,1)'></td>
+ <td width='1' style='background-color: rgba(145,138,178,1)'></td>
+ <td width='1' style='background-color: rgba(138,138,183,1)'></td>
+ <td width='1' style='background-color: rgba(130,138,189,1)'></td>
+ <td width='1' style='background-color: rgba(121,138,194,1)'></td>
+ <td width='1' style='background-color: rgba(111,138,199,1)'></td>
+ <td width='1' style='background-color: rgba(100,138,204,1)'></td>
+ <td width='1' style='background-color: rgba(88,138,209,1)'></td>
+ <td width='1' style='background-color: rgba(73,138,214,1)'></td>
+ <td width='1' style='background-color: rgba(53,138,218,1)'></td>
+ <td width='1' style='background-color: rgba(0,138,223,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,130,0,1)'></td>
+ <td width='1' style='background-color: rgba(223,130,53,1)'></td>
+ <td width='1' style='background-color: rgba(218,130,73,1)'></td>
+ <td width='1' style='background-color: rgba(214,130,88,1)'></td>
+ <td width='1' style='background-color: rgba(209,130,100,1)'></td>
+ <td width='1' style='background-color: rgba(204,130,111,1)'></td>
+ <td width='1' style='background-color: rgba(199,130,121,1)'></td>
+ <td width='1' style='background-color: rgba(194,130,130,1)'></td>
+ <td width='1' style='background-color: rgba(189,130,138,1)'></td>
+ <td width='1' style='background-color: rgba(183,130,145,1)'></td>
+ <td width='1' style='background-color: rgba(178,130,152,1)'></td>
+ <td width='1' style='background-color: rgba(172,130,159,1)'></td>
+ <td width='1' style='background-color: rgba(166,130,166,1)'></td>
+ <td width='1' style='background-color: rgba(159,130,172,1)'></td>
+ <td width='1' style='background-color: rgba(152,130,178,1)'></td>
+ <td width='1' style='background-color: rgba(145,130,183,1)'></td>
+ <td width='1' style='background-color: rgba(138,130,189,1)'></td>
+ <td width='1' style='background-color: rgba(130,130,194,1)'></td>
+ <td width='1' style='background-color: rgba(121,130,199,1)'></td>
+ <td width='1' style='background-color: rgba(111,130,204,1)'></td>
+ <td width='1' style='background-color: rgba(100,130,209,1)'></td>
+ <td width='1' style='background-color: rgba(88,130,214,1)'></td>
+ <td width='1' style='background-color: rgba(73,130,218,1)'></td>
+ <td width='1' style='background-color: rgba(53,130,223,1)'></td>
+ <td width='1' style='background-color: rgba(0,130,227,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,121,0,1)'></td>
+ <td width='1' style='background-color: rgba(227,121,53,1)'></td>
+ <td width='1' style='background-color: rgba(223,121,73,1)'></td>
+ <td width='1' style='background-color: rgba(218,121,88,1)'></td>
+ <td width='1' style='background-color: rgba(214,121,100,1)'></td>
+ <td width='1' style='background-color: rgba(209,121,111,1)'></td>
+ <td width='1' style='background-color: rgba(204,121,121,1)'></td>
+ <td width='1' style='background-color: rgba(199,121,130,1)'></td>
+ <td width='1' style='background-color: rgba(194,121,138,1)'></td>
+ <td width='1' style='background-color: rgba(189,121,145,1)'></td>
+ <td width='1' style='background-color: rgba(183,121,152,1)'></td>
+ <td width='1' style='background-color: rgba(178,121,159,1)'></td>
+ <td width='1' style='background-color: rgba(172,121,166,1)'></td>
+ <td width='1' style='background-color: rgba(166,121,172,1)'></td>
+ <td width='1' style='background-color: rgba(159,121,178,1)'></td>
+ <td width='1' style='background-color: rgba(152,121,183,1)'></td>
+ <td width='1' style='background-color: rgba(145,121,189,1)'></td>
+ <td width='1' style='background-color: rgba(138,121,194,1)'></td>
+ <td width='1' style='background-color: rgba(130,121,199,1)'></td>
+ <td width='1' style='background-color: rgba(121,121,204,1)'></td>
+ <td width='1' style='background-color: rgba(111,121,209,1)'></td>
+ <td width='1' style='background-color: rgba(100,121,214,1)'></td>
+ <td width='1' style='background-color: rgba(88,121,218,1)'></td>
+ <td width='1' style='background-color: rgba(73,121,223,1)'></td>
+ <td width='1' style='background-color: rgba(53,121,227,1)'></td>
+ <td width='1' style='background-color: rgba(0,121,231,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,111,0,1)'></td>
+ <td width='1' style='background-color: rgba(231,111,53,1)'></td>
+ <td width='1' style='background-color: rgba(227,111,73,1)'></td>
+ <td width='1' style='background-color: rgba(223,111,88,1)'></td>
+ <td width='1' style='background-color: rgba(218,111,100,1)'></td>
+ <td width='1' style='background-color: rgba(214,111,111,1)'></td>
+ <td width='1' style='background-color: rgba(209,111,121,1)'></td>
+ <td width='1' style='background-color: rgba(204,111,130,1)'></td>
+ <td width='1' style='background-color: rgba(199,111,138,1)'></td>
+ <td width='1' style='background-color: rgba(194,111,145,1)'></td>
+ <td width='1' style='background-color: rgba(189,111,152,1)'></td>
+ <td width='1' style='background-color: rgba(183,111,159,1)'></td>
+ <td width='1' style='background-color: rgba(178,111,166,1)'></td>
+ <td width='1' style='background-color: rgba(172,111,172,1)'></td>
+ <td width='1' style='background-color: rgba(166,111,178,1)'></td>
+ <td width='1' style='background-color: rgba(159,111,183,1)'></td>
+ <td width='1' style='background-color: rgba(152,111,189,1)'></td>
+ <td width='1' style='background-color: rgba(145,111,194,1)'></td>
+ <td width='1' style='background-color: rgba(138,111,199,1)'></td>
+ <td width='1' style='background-color: rgba(130,111,204,1)'></td>
+ <td width='1' style='background-color: rgba(121,111,209,1)'></td>
+ <td width='1' style='background-color: rgba(111,111,214,1)'></td>
+ <td width='1' style='background-color: rgba(100,111,218,1)'></td>
+ <td width='1' style='background-color: rgba(88,111,223,1)'></td>
+ <td width='1' style='background-color: rgba(73,111,227,1)'></td>
+ <td width='1' style='background-color: rgba(53,111,231,1)'></td>
+ <td width='1' style='background-color: rgba(0,111,235,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,100,0,1)'></td>
+ <td width='1' style='background-color: rgba(235,100,53,1)'></td>
+ <td width='1' style='background-color: rgba(231,100,73,1)'></td>
+ <td width='1' style='background-color: rgba(227,100,88,1)'></td>
+ <td width='1' style='background-color: rgba(223,100,100,1)'></td>
+ <td width='1' style='background-color: rgba(218,100,111,1)'></td>
+ <td width='1' style='background-color: rgba(214,100,121,1)'></td>
+ <td width='1' style='background-color: rgba(209,100,130,1)'></td>
+ <td width='1' style='background-color: rgba(204,100,138,1)'></td>
+ <td width='1' style='background-color: rgba(199,100,145,1)'></td>
+ <td width='1' style='background-color: rgba(194,100,152,1)'></td>
+ <td width='1' style='background-color: rgba(189,100,159,1)'></td>
+ <td width='1' style='background-color: rgba(183,100,166,1)'></td>
+ <td width='1' style='background-color: rgba(178,100,172,1)'></td>
+ <td width='1' style='background-color: rgba(172,100,178,1)'></td>
+ <td width='1' style='background-color: rgba(166,100,183,1)'></td>
+ <td width='1' style='background-color: rgba(159,100,189,1)'></td>
+ <td width='1' style='background-color: rgba(152,100,194,1)'></td>
+ <td width='1' style='background-color: rgba(145,100,199,1)'></td>
+ <td width='1' style='background-color: rgba(138,100,204,1)'></td>
+ <td width='1' style='background-color: rgba(130,100,209,1)'></td>
+ <td width='1' style='background-color: rgba(121,100,214,1)'></td>
+ <td width='1' style='background-color: rgba(111,100,218,1)'></td>
+ <td width='1' style='background-color: rgba(100,100,223,1)'></td>
+ <td width='1' style='background-color: rgba(88,100,227,1)'></td>
+ <td width='1' style='background-color: rgba(73,100,231,1)'></td>
+ <td width='1' style='background-color: rgba(53,100,235,1)'></td>
+ <td width='1' style='background-color: rgba(0,100,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,88,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,88,53,1)'></td>
+ <td width='1' style='background-color: rgba(235,88,73,1)'></td>
+ <td width='1' style='background-color: rgba(231,88,88,1)'></td>
+ <td width='1' style='background-color: rgba(227,88,100,1)'></td>
+ <td width='1' style='background-color: rgba(223,88,111,1)'></td>
+ <td width='1' style='background-color: rgba(218,88,121,1)'></td>
+ <td width='1' style='background-color: rgba(214,88,130,1)'></td>
+ <td width='1' style='background-color: rgba(209,88,138,1)'></td>
+ <td width='1' style='background-color: rgba(204,88,145,1)'></td>
+ <td width='1' style='background-color: rgba(199,88,152,1)'></td>
+ <td width='1' style='background-color: rgba(194,88,159,1)'></td>
+ <td width='1' style='background-color: rgba(189,88,166,1)'></td>
+ <td width='1' style='background-color: rgba(183,88,172,1)'></td>
+ <td width='1' style='background-color: rgba(178,88,178,1)'></td>
+ <td width='1' style='background-color: rgba(172,88,183,1)'></td>
+ <td width='1' style='background-color: rgba(166,88,189,1)'></td>
+ <td width='1' style='background-color: rgba(159,88,194,1)'></td>
+ <td width='1' style='background-color: rgba(152,88,199,1)'></td>
+ <td width='1' style='background-color: rgba(145,88,204,1)'></td>
+ <td width='1' style='background-color: rgba(138,88,209,1)'></td>
+ <td width='1' style='background-color: rgba(130,88,214,1)'></td>
+ <td width='1' style='background-color: rgba(121,88,218,1)'></td>
+ <td width='1' style='background-color: rgba(111,88,223,1)'></td>
+ <td width='1' style='background-color: rgba(100,88,227,1)'></td>
+ <td width='1' style='background-color: rgba(88,88,231,1)'></td>
+ <td width='1' style='background-color: rgba(73,88,235,1)'></td>
+ <td width='1' style='background-color: rgba(53,88,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,88,243,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,73,0,1)'></td>
+ <td width='1' style='background-color: rgba(243,73,53,1)'></td>
+ <td width='1' style='background-color: rgba(239,73,73,1)'></td>
+ <td width='1' style='background-color: rgba(235,73,88,1)'></td>
+ <td width='1' style='background-color: rgba(231,73,100,1)'></td>
+ <td width='1' style='background-color: rgba(227,73,111,1)'></td>
+ <td width='1' style='background-color: rgba(223,73,121,1)'></td>
+ <td width='1' style='background-color: rgba(218,73,130,1)'></td>
+ <td width='1' style='background-color: rgba(214,73,138,1)'></td>
+ <td width='1' style='background-color: rgba(209,73,145,1)'></td>
+ <td width='1' style='background-color: rgba(204,73,152,1)'></td>
+ <td width='1' style='background-color: rgba(199,73,159,1)'></td>
+ <td width='1' style='background-color: rgba(194,73,166,1)'></td>
+ <td width='1' style='background-color: rgba(189,73,172,1)'></td>
+ <td width='1' style='background-color: rgba(183,73,178,1)'></td>
+ <td width='1' style='background-color: rgba(178,73,183,1)'></td>
+ <td width='1' style='background-color: rgba(172,73,189,1)'></td>
+ <td width='1' style='background-color: rgba(166,73,194,1)'></td>
+ <td width='1' style='background-color: rgba(159,73,199,1)'></td>
+ <td width='1' style='background-color: rgba(152,73,204,1)'></td>
+ <td width='1' style='background-color: rgba(145,73,209,1)'></td>
+ <td width='1' style='background-color: rgba(138,73,214,1)'></td>
+ <td width='1' style='background-color: rgba(130,73,218,1)'></td>
+ <td width='1' style='background-color: rgba(121,73,223,1)'></td>
+ <td width='1' style='background-color: rgba(111,73,227,1)'></td>
+ <td width='1' style='background-color: rgba(100,73,231,1)'></td>
+ <td width='1' style='background-color: rgba(88,73,235,1)'></td>
+ <td width='1' style='background-color: rgba(73,73,239,1)'></td>
+ <td width='1' style='background-color: rgba(53,73,243,1)'></td>
+ <td width='1' style='background-color: rgba(0,73,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,53,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,53,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,53,53,1)'></td>
+ <td width='1' style='background-color: rgba(243,53,73,1)'></td>
+ <td width='1' style='background-color: rgba(239,53,88,1)'></td>
+ <td width='1' style='background-color: rgba(235,53,100,1)'></td>
+ <td width='1' style='background-color: rgba(231,53,111,1)'></td>
+ <td width='1' style='background-color: rgba(227,53,121,1)'></td>
+ <td width='1' style='background-color: rgba(223,53,130,1)'></td>
+ <td width='1' style='background-color: rgba(218,53,138,1)'></td>
+ <td width='1' style='background-color: rgba(214,53,145,1)'></td>
+ <td width='1' style='background-color: rgba(209,53,152,1)'></td>
+ <td width='1' style='background-color: rgba(204,53,159,1)'></td>
+ <td width='1' style='background-color: rgba(199,53,166,1)'></td>
+ <td width='1' style='background-color: rgba(194,53,172,1)'></td>
+ <td width='1' style='background-color: rgba(189,53,178,1)'></td>
+ <td width='1' style='background-color: rgba(183,53,183,1)'></td>
+ <td width='1' style='background-color: rgba(178,53,189,1)'></td>
+ <td width='1' style='background-color: rgba(172,53,194,1)'></td>
+ <td width='1' style='background-color: rgba(166,53,199,1)'></td>
+ <td width='1' style='background-color: rgba(159,53,204,1)'></td>
+ <td width='1' style='background-color: rgba(152,53,209,1)'></td>
+ <td width='1' style='background-color: rgba(145,53,214,1)'></td>
+ <td width='1' style='background-color: rgba(138,53,218,1)'></td>
+ <td width='1' style='background-color: rgba(130,53,223,1)'></td>
+ <td width='1' style='background-color: rgba(121,53,227,1)'></td>
+ <td width='1' style='background-color: rgba(111,53,231,1)'></td>
+ <td width='1' style='background-color: rgba(100,53,235,1)'></td>
+ <td width='1' style='background-color: rgba(88,53,239,1)'></td>
+ <td width='1' style='background-color: rgba(73,53,243,1)'></td>
+ <td width='1' style='background-color: rgba(53,53,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,53,251,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(251,0,53,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,73,1)'></td>
+ <td width='1' style='background-color: rgba(243,0,88,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,100,1)'></td>
+ <td width='1' style='background-color: rgba(235,0,111,1)'></td>
+ <td width='1' style='background-color: rgba(231,0,121,1)'></td>
+ <td width='1' style='background-color: rgba(227,0,130,1)'></td>
+ <td width='1' style='background-color: rgba(223,0,138,1)'></td>
+ <td width='1' style='background-color: rgba(218,0,145,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,152,1)'></td>
+ <td width='1' style='background-color: rgba(209,0,159,1)'></td>
+ <td width='1' style='background-color: rgba(204,0,166,1)'></td>
+ <td width='1' style='background-color: rgba(199,0,172,1)'></td>
+ <td width='1' style='background-color: rgba(194,0,178,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,183,1)'></td>
+ <td width='1' style='background-color: rgba(183,0,189,1)'></td>
+ <td width='1' style='background-color: rgba(178,0,194,1)'></td>
+ <td width='1' style='background-color: rgba(172,0,199,1)'></td>
+ <td width='1' style='background-color: rgba(166,0,204,1)'></td>
+ <td width='1' style='background-color: rgba(159,0,209,1)'></td>
+ <td width='1' style='background-color: rgba(152,0,214,1)'></td>
+ <td width='1' style='background-color: rgba(145,0,218,1)'></td>
+ <td width='1' style='background-color: rgba(138,0,223,1)'></td>
+ <td width='1' style='background-color: rgba(130,0,227,1)'></td>
+ <td width='1' style='background-color: rgba(121,0,231,1)'></td>
+ <td width='1' style='background-color: rgba(111,0,235,1)'></td>
+ <td width='1' style='background-color: rgba(100,0,239,1)'></td>
+ <td width='1' style='background-color: rgba(88,0,243,1)'></td>
+ <td width='1' style='background-color: rgba(73,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(53,0,251,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-palettes/ps2n2c16.png b/image/test/reftest/pngsuite-palettes/ps2n2c16.png
new file mode 100644
index 0000000000..c256f9091b
--- /dev/null
+++ b/image/test/reftest/pngsuite-palettes/ps2n2c16.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-palettes/reftest.list b/image/test/reftest/pngsuite-palettes/reftest.list
new file mode 100644
index 0000000000..56eb56e0a2
--- /dev/null
+++ b/image/test/reftest/pngsuite-palettes/reftest.list
@@ -0,0 +1,14 @@
+# PngSuite - Additional palettes
+
+# pp0n2c16 - six-cube palette-chunk in true-color image
+== pp0n2c16.png pp0n2c16.html
+# pp0n6a08 - six-cube palette-chunk in true-color+alpha image
+#== pp0n6a08.png pp0n6a08.html
+# ps1n0g08 - six-cube suggested palette (1 byte) in grayscale image
+== ps1n0g08.png ps1n0g08.html
+# ps1n2c16 - six-cube suggested palette (1 byte) in true-color image
+== ps1n2c16.png ps1n2c16.html
+# ps2n0g08 - six-cube suggested palette (2 bytes) in grayscale image
+== ps2n0g08.png ps2n0g08.html
+# ps2n2c16 - six-cube suggested palette (2 bytes) in true-color image
+== ps2n2c16.png ps2n2c16.html
diff --git a/image/test/reftest/pngsuite-zlib/reftest.list b/image/test/reftest/pngsuite-zlib/reftest.list
new file mode 100644
index 0000000000..ec153449fb
--- /dev/null
+++ b/image/test/reftest/pngsuite-zlib/reftest.list
@@ -0,0 +1,8 @@
+# z00n2c08 - color, no interlacing, compression level 0 (none)
+== z00n2c08.png z00n2c08.html
+# z03n2c08 - color, no interlacing, compression level 3
+== z03n2c08.png z03n2c08.html
+# z06n2c08 - color, no interlacing, compression level 6 (default)
+== z06n2c08.png z06n2c08.html
+# z09n2c08 - color, no interlacing, compression level 9 (maximum)
+== z09n2c08.png z09n2c08.html
diff --git a/image/test/reftest/pngsuite-zlib/z00n2c08.html b/image/test/reftest/pngsuite-zlib/z00n2c08.html
new file mode 100644
index 0000000000..c878a03ff6
--- /dev/null
+++ b/image/test/reftest/pngsuite-zlib/z00n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(8,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(8,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,8,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(8,239,8,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,16,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,230,8,1)'></td>
+ <td width='1' style='background-color: rgba(8,230,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,25,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,222,8,1)'></td>
+ <td width='1' style='background-color: rgba(16,222,16,1)'></td>
+ <td width='1' style='background-color: rgba(8,222,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,222,33,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,214,8,1)'></td>
+ <td width='1' style='background-color: rgba(25,214,16,1)'></td>
+ <td width='1' style='background-color: rgba(16,214,25,1)'></td>
+ <td width='1' style='background-color: rgba(8,214,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,214,41,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,206,8,1)'></td>
+ <td width='1' style='background-color: rgba(33,206,16,1)'></td>
+ <td width='1' style='background-color: rgba(25,206,25,1)'></td>
+ <td width='1' style='background-color: rgba(16,206,33,1)'></td>
+ <td width='1' style='background-color: rgba(8,206,41,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,49,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,197,8,1)'></td>
+ <td width='1' style='background-color: rgba(41,197,16,1)'></td>
+ <td width='1' style='background-color: rgba(33,197,25,1)'></td>
+ <td width='1' style='background-color: rgba(25,197,33,1)'></td>
+ <td width='1' style='background-color: rgba(16,197,41,1)'></td>
+ <td width='1' style='background-color: rgba(8,197,49,1)'></td>
+ <td width='1' style='background-color: rgba(0,197,58,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,189,8,1)'></td>
+ <td width='1' style='background-color: rgba(49,189,16,1)'></td>
+ <td width='1' style='background-color: rgba(41,189,25,1)'></td>
+ <td width='1' style='background-color: rgba(33,189,33,1)'></td>
+ <td width='1' style='background-color: rgba(25,189,41,1)'></td>
+ <td width='1' style='background-color: rgba(16,189,49,1)'></td>
+ <td width='1' style='background-color: rgba(8,189,58,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,66,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,181,8,1)'></td>
+ <td width='1' style='background-color: rgba(58,181,16,1)'></td>
+ <td width='1' style='background-color: rgba(49,181,25,1)'></td>
+ <td width='1' style='background-color: rgba(41,181,33,1)'></td>
+ <td width='1' style='background-color: rgba(33,181,41,1)'></td>
+ <td width='1' style='background-color: rgba(25,181,49,1)'></td>
+ <td width='1' style='background-color: rgba(16,181,58,1)'></td>
+ <td width='1' style='background-color: rgba(8,181,66,1)'></td>
+ <td width='1' style='background-color: rgba(0,181,74,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,173,8,1)'></td>
+ <td width='1' style='background-color: rgba(66,173,16,1)'></td>
+ <td width='1' style='background-color: rgba(58,173,25,1)'></td>
+ <td width='1' style='background-color: rgba(49,173,33,1)'></td>
+ <td width='1' style='background-color: rgba(41,173,41,1)'></td>
+ <td width='1' style='background-color: rgba(33,173,49,1)'></td>
+ <td width='1' style='background-color: rgba(25,173,58,1)'></td>
+ <td width='1' style='background-color: rgba(16,173,66,1)'></td>
+ <td width='1' style='background-color: rgba(8,173,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,82,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,165,8,1)'></td>
+ <td width='1' style='background-color: rgba(74,165,16,1)'></td>
+ <td width='1' style='background-color: rgba(66,165,25,1)'></td>
+ <td width='1' style='background-color: rgba(58,165,33,1)'></td>
+ <td width='1' style='background-color: rgba(49,165,41,1)'></td>
+ <td width='1' style='background-color: rgba(41,165,49,1)'></td>
+ <td width='1' style='background-color: rgba(33,165,58,1)'></td>
+ <td width='1' style='background-color: rgba(25,165,66,1)'></td>
+ <td width='1' style='background-color: rgba(16,165,74,1)'></td>
+ <td width='1' style='background-color: rgba(8,165,82,1)'></td>
+ <td width='1' style='background-color: rgba(0,165,90,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,156,8,1)'></td>
+ <td width='1' style='background-color: rgba(82,156,16,1)'></td>
+ <td width='1' style='background-color: rgba(74,156,25,1)'></td>
+ <td width='1' style='background-color: rgba(66,156,33,1)'></td>
+ <td width='1' style='background-color: rgba(58,156,41,1)'></td>
+ <td width='1' style='background-color: rgba(49,156,49,1)'></td>
+ <td width='1' style='background-color: rgba(41,156,58,1)'></td>
+ <td width='1' style='background-color: rgba(33,156,66,1)'></td>
+ <td width='1' style='background-color: rgba(25,156,74,1)'></td>
+ <td width='1' style='background-color: rgba(16,156,82,1)'></td>
+ <td width='1' style='background-color: rgba(8,156,90,1)'></td>
+ <td width='1' style='background-color: rgba(0,156,99,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,148,8,1)'></td>
+ <td width='1' style='background-color: rgba(90,148,16,1)'></td>
+ <td width='1' style='background-color: rgba(82,148,25,1)'></td>
+ <td width='1' style='background-color: rgba(74,148,33,1)'></td>
+ <td width='1' style='background-color: rgba(66,148,41,1)'></td>
+ <td width='1' style='background-color: rgba(58,148,49,1)'></td>
+ <td width='1' style='background-color: rgba(49,148,58,1)'></td>
+ <td width='1' style='background-color: rgba(41,148,66,1)'></td>
+ <td width='1' style='background-color: rgba(33,148,74,1)'></td>
+ <td width='1' style='background-color: rgba(25,148,82,1)'></td>
+ <td width='1' style='background-color: rgba(16,148,90,1)'></td>
+ <td width='1' style='background-color: rgba(8,148,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,148,107,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,140,8,1)'></td>
+ <td width='1' style='background-color: rgba(99,140,16,1)'></td>
+ <td width='1' style='background-color: rgba(90,140,25,1)'></td>
+ <td width='1' style='background-color: rgba(82,140,33,1)'></td>
+ <td width='1' style='background-color: rgba(74,140,41,1)'></td>
+ <td width='1' style='background-color: rgba(66,140,49,1)'></td>
+ <td width='1' style='background-color: rgba(58,140,58,1)'></td>
+ <td width='1' style='background-color: rgba(49,140,66,1)'></td>
+ <td width='1' style='background-color: rgba(41,140,74,1)'></td>
+ <td width='1' style='background-color: rgba(33,140,82,1)'></td>
+ <td width='1' style='background-color: rgba(25,140,90,1)'></td>
+ <td width='1' style='background-color: rgba(16,140,99,1)'></td>
+ <td width='1' style='background-color: rgba(8,140,107,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,115,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,132,8,1)'></td>
+ <td width='1' style='background-color: rgba(107,132,16,1)'></td>
+ <td width='1' style='background-color: rgba(99,132,25,1)'></td>
+ <td width='1' style='background-color: rgba(90,132,33,1)'></td>
+ <td width='1' style='background-color: rgba(82,132,41,1)'></td>
+ <td width='1' style='background-color: rgba(74,132,49,1)'></td>
+ <td width='1' style='background-color: rgba(66,132,58,1)'></td>
+ <td width='1' style='background-color: rgba(58,132,66,1)'></td>
+ <td width='1' style='background-color: rgba(49,132,74,1)'></td>
+ <td width='1' style='background-color: rgba(41,132,82,1)'></td>
+ <td width='1' style='background-color: rgba(33,132,90,1)'></td>
+ <td width='1' style='background-color: rgba(25,132,99,1)'></td>
+ <td width='1' style='background-color: rgba(16,132,107,1)'></td>
+ <td width='1' style='background-color: rgba(8,132,115,1)'></td>
+ <td width='1' style='background-color: rgba(0,132,123,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,8,1)'></td>
+ <td width='1' style='background-color: rgba(115,123,16,1)'></td>
+ <td width='1' style='background-color: rgba(107,123,25,1)'></td>
+ <td width='1' style='background-color: rgba(99,123,33,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,41,1)'></td>
+ <td width='1' style='background-color: rgba(82,123,49,1)'></td>
+ <td width='1' style='background-color: rgba(74,123,58,1)'></td>
+ <td width='1' style='background-color: rgba(66,123,66,1)'></td>
+ <td width='1' style='background-color: rgba(58,123,74,1)'></td>
+ <td width='1' style='background-color: rgba(49,123,82,1)'></td>
+ <td width='1' style='background-color: rgba(41,123,90,1)'></td>
+ <td width='1' style='background-color: rgba(33,123,99,1)'></td>
+ <td width='1' style='background-color: rgba(25,123,107,1)'></td>
+ <td width='1' style='background-color: rgba(16,123,115,1)'></td>
+ <td width='1' style='background-color: rgba(8,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,132,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,115,8,1)'></td>
+ <td width='1' style='background-color: rgba(123,115,16,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,25,1)'></td>
+ <td width='1' style='background-color: rgba(107,115,33,1)'></td>
+ <td width='1' style='background-color: rgba(99,115,41,1)'></td>
+ <td width='1' style='background-color: rgba(90,115,49,1)'></td>
+ <td width='1' style='background-color: rgba(82,115,58,1)'></td>
+ <td width='1' style='background-color: rgba(74,115,66,1)'></td>
+ <td width='1' style='background-color: rgba(66,115,74,1)'></td>
+ <td width='1' style='background-color: rgba(58,115,82,1)'></td>
+ <td width='1' style='background-color: rgba(49,115,90,1)'></td>
+ <td width='1' style='background-color: rgba(41,115,99,1)'></td>
+ <td width='1' style='background-color: rgba(33,115,107,1)'></td>
+ <td width='1' style='background-color: rgba(25,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(16,115,123,1)'></td>
+ <td width='1' style='background-color: rgba(8,115,132,1)'></td>
+ <td width='1' style='background-color: rgba(0,115,140,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,107,8,1)'></td>
+ <td width='1' style='background-color: rgba(132,107,16,1)'></td>
+ <td width='1' style='background-color: rgba(123,107,25,1)'></td>
+ <td width='1' style='background-color: rgba(115,107,33,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,41,1)'></td>
+ <td width='1' style='background-color: rgba(99,107,49,1)'></td>
+ <td width='1' style='background-color: rgba(90,107,58,1)'></td>
+ <td width='1' style='background-color: rgba(82,107,66,1)'></td>
+ <td width='1' style='background-color: rgba(74,107,74,1)'></td>
+ <td width='1' style='background-color: rgba(66,107,82,1)'></td>
+ <td width='1' style='background-color: rgba(58,107,90,1)'></td>
+ <td width='1' style='background-color: rgba(49,107,99,1)'></td>
+ <td width='1' style='background-color: rgba(41,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(33,107,115,1)'></td>
+ <td width='1' style='background-color: rgba(25,107,123,1)'></td>
+ <td width='1' style='background-color: rgba(16,107,132,1)'></td>
+ <td width='1' style='background-color: rgba(8,107,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,107,148,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,99,8,1)'></td>
+ <td width='1' style='background-color: rgba(140,99,16,1)'></td>
+ <td width='1' style='background-color: rgba(132,99,25,1)'></td>
+ <td width='1' style='background-color: rgba(123,99,33,1)'></td>
+ <td width='1' style='background-color: rgba(115,99,41,1)'></td>
+ <td width='1' style='background-color: rgba(107,99,49,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,58,1)'></td>
+ <td width='1' style='background-color: rgba(90,99,66,1)'></td>
+ <td width='1' style='background-color: rgba(82,99,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,99,82,1)'></td>
+ <td width='1' style='background-color: rgba(66,99,90,1)'></td>
+ <td width='1' style='background-color: rgba(58,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(49,99,107,1)'></td>
+ <td width='1' style='background-color: rgba(41,99,115,1)'></td>
+ <td width='1' style='background-color: rgba(33,99,123,1)'></td>
+ <td width='1' style='background-color: rgba(25,99,132,1)'></td>
+ <td width='1' style='background-color: rgba(16,99,140,1)'></td>
+ <td width='1' style='background-color: rgba(8,99,148,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,156,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,90,8,1)'></td>
+ <td width='1' style='background-color: rgba(148,90,16,1)'></td>
+ <td width='1' style='background-color: rgba(140,90,25,1)'></td>
+ <td width='1' style='background-color: rgba(132,90,33,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,41,1)'></td>
+ <td width='1' style='background-color: rgba(115,90,49,1)'></td>
+ <td width='1' style='background-color: rgba(107,90,58,1)'></td>
+ <td width='1' style='background-color: rgba(99,90,66,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,74,1)'></td>
+ <td width='1' style='background-color: rgba(82,90,82,1)'></td>
+ <td width='1' style='background-color: rgba(74,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(66,90,99,1)'></td>
+ <td width='1' style='background-color: rgba(58,90,107,1)'></td>
+ <td width='1' style='background-color: rgba(49,90,115,1)'></td>
+ <td width='1' style='background-color: rgba(41,90,123,1)'></td>
+ <td width='1' style='background-color: rgba(33,90,132,1)'></td>
+ <td width='1' style='background-color: rgba(25,90,140,1)'></td>
+ <td width='1' style='background-color: rgba(16,90,148,1)'></td>
+ <td width='1' style='background-color: rgba(8,90,156,1)'></td>
+ <td width='1' style='background-color: rgba(0,90,165,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,82,8,1)'></td>
+ <td width='1' style='background-color: rgba(156,82,16,1)'></td>
+ <td width='1' style='background-color: rgba(148,82,25,1)'></td>
+ <td width='1' style='background-color: rgba(140,82,33,1)'></td>
+ <td width='1' style='background-color: rgba(132,82,41,1)'></td>
+ <td width='1' style='background-color: rgba(123,82,49,1)'></td>
+ <td width='1' style='background-color: rgba(115,82,58,1)'></td>
+ <td width='1' style='background-color: rgba(107,82,66,1)'></td>
+ <td width='1' style='background-color: rgba(99,82,74,1)'></td>
+ <td width='1' style='background-color: rgba(90,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,90,1)'></td>
+ <td width='1' style='background-color: rgba(74,82,99,1)'></td>
+ <td width='1' style='background-color: rgba(66,82,107,1)'></td>
+ <td width='1' style='background-color: rgba(58,82,115,1)'></td>
+ <td width='1' style='background-color: rgba(49,82,123,1)'></td>
+ <td width='1' style='background-color: rgba(41,82,132,1)'></td>
+ <td width='1' style='background-color: rgba(33,82,140,1)'></td>
+ <td width='1' style='background-color: rgba(25,82,148,1)'></td>
+ <td width='1' style='background-color: rgba(16,82,156,1)'></td>
+ <td width='1' style='background-color: rgba(8,82,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,82,173,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,74,8,1)'></td>
+ <td width='1' style='background-color: rgba(165,74,16,1)'></td>
+ <td width='1' style='background-color: rgba(156,74,25,1)'></td>
+ <td width='1' style='background-color: rgba(148,74,33,1)'></td>
+ <td width='1' style='background-color: rgba(140,74,41,1)'></td>
+ <td width='1' style='background-color: rgba(132,74,49,1)'></td>
+ <td width='1' style='background-color: rgba(123,74,58,1)'></td>
+ <td width='1' style='background-color: rgba(115,74,66,1)'></td>
+ <td width='1' style='background-color: rgba(107,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(99,74,82,1)'></td>
+ <td width='1' style='background-color: rgba(90,74,90,1)'></td>
+ <td width='1' style='background-color: rgba(82,74,99,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,107,1)'></td>
+ <td width='1' style='background-color: rgba(66,74,115,1)'></td>
+ <td width='1' style='background-color: rgba(58,74,123,1)'></td>
+ <td width='1' style='background-color: rgba(49,74,132,1)'></td>
+ <td width='1' style='background-color: rgba(41,74,140,1)'></td>
+ <td width='1' style='background-color: rgba(33,74,148,1)'></td>
+ <td width='1' style='background-color: rgba(25,74,156,1)'></td>
+ <td width='1' style='background-color: rgba(16,74,165,1)'></td>
+ <td width='1' style='background-color: rgba(8,74,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,181,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,66,8,1)'></td>
+ <td width='1' style='background-color: rgba(173,66,16,1)'></td>
+ <td width='1' style='background-color: rgba(165,66,25,1)'></td>
+ <td width='1' style='background-color: rgba(156,66,33,1)'></td>
+ <td width='1' style='background-color: rgba(148,66,41,1)'></td>
+ <td width='1' style='background-color: rgba(140,66,49,1)'></td>
+ <td width='1' style='background-color: rgba(132,66,58,1)'></td>
+ <td width='1' style='background-color: rgba(123,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(115,66,74,1)'></td>
+ <td width='1' style='background-color: rgba(107,66,82,1)'></td>
+ <td width='1' style='background-color: rgba(99,66,90,1)'></td>
+ <td width='1' style='background-color: rgba(90,66,99,1)'></td>
+ <td width='1' style='background-color: rgba(82,66,107,1)'></td>
+ <td width='1' style='background-color: rgba(74,66,115,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,123,1)'></td>
+ <td width='1' style='background-color: rgba(58,66,132,1)'></td>
+ <td width='1' style='background-color: rgba(49,66,140,1)'></td>
+ <td width='1' style='background-color: rgba(41,66,148,1)'></td>
+ <td width='1' style='background-color: rgba(33,66,156,1)'></td>
+ <td width='1' style='background-color: rgba(25,66,165,1)'></td>
+ <td width='1' style='background-color: rgba(16,66,173,1)'></td>
+ <td width='1' style='background-color: rgba(8,66,181,1)'></td>
+ <td width='1' style='background-color: rgba(0,66,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,58,8,1)'></td>
+ <td width='1' style='background-color: rgba(181,58,16,1)'></td>
+ <td width='1' style='background-color: rgba(173,58,25,1)'></td>
+ <td width='1' style='background-color: rgba(165,58,33,1)'></td>
+ <td width='1' style='background-color: rgba(156,58,41,1)'></td>
+ <td width='1' style='background-color: rgba(148,58,49,1)'></td>
+ <td width='1' style='background-color: rgba(140,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(132,58,66,1)'></td>
+ <td width='1' style='background-color: rgba(123,58,74,1)'></td>
+ <td width='1' style='background-color: rgba(115,58,82,1)'></td>
+ <td width='1' style='background-color: rgba(107,58,90,1)'></td>
+ <td width='1' style='background-color: rgba(99,58,99,1)'></td>
+ <td width='1' style='background-color: rgba(90,58,107,1)'></td>
+ <td width='1' style='background-color: rgba(82,58,115,1)'></td>
+ <td width='1' style='background-color: rgba(74,58,123,1)'></td>
+ <td width='1' style='background-color: rgba(66,58,132,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,140,1)'></td>
+ <td width='1' style='background-color: rgba(49,58,148,1)'></td>
+ <td width='1' style='background-color: rgba(41,58,156,1)'></td>
+ <td width='1' style='background-color: rgba(33,58,165,1)'></td>
+ <td width='1' style='background-color: rgba(25,58,173,1)'></td>
+ <td width='1' style='background-color: rgba(16,58,181,1)'></td>
+ <td width='1' style='background-color: rgba(8,58,189,1)'></td>
+ <td width='1' style='background-color: rgba(0,58,197,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,49,8,1)'></td>
+ <td width='1' style='background-color: rgba(189,49,16,1)'></td>
+ <td width='1' style='background-color: rgba(181,49,25,1)'></td>
+ <td width='1' style='background-color: rgba(173,49,33,1)'></td>
+ <td width='1' style='background-color: rgba(165,49,41,1)'></td>
+ <td width='1' style='background-color: rgba(156,49,49,1)'></td>
+ <td width='1' style='background-color: rgba(148,49,58,1)'></td>
+ <td width='1' style='background-color: rgba(140,49,66,1)'></td>
+ <td width='1' style='background-color: rgba(132,49,74,1)'></td>
+ <td width='1' style='background-color: rgba(123,49,82,1)'></td>
+ <td width='1' style='background-color: rgba(115,49,90,1)'></td>
+ <td width='1' style='background-color: rgba(107,49,99,1)'></td>
+ <td width='1' style='background-color: rgba(99,49,107,1)'></td>
+ <td width='1' style='background-color: rgba(90,49,115,1)'></td>
+ <td width='1' style='background-color: rgba(82,49,123,1)'></td>
+ <td width='1' style='background-color: rgba(74,49,132,1)'></td>
+ <td width='1' style='background-color: rgba(66,49,140,1)'></td>
+ <td width='1' style='background-color: rgba(58,49,148,1)'></td>
+ <td width='1' style='background-color: rgba(49,49,156,1)'></td>
+ <td width='1' style='background-color: rgba(41,49,165,1)'></td>
+ <td width='1' style='background-color: rgba(33,49,173,1)'></td>
+ <td width='1' style='background-color: rgba(25,49,181,1)'></td>
+ <td width='1' style='background-color: rgba(16,49,189,1)'></td>
+ <td width='1' style='background-color: rgba(8,49,197,1)'></td>
+ <td width='1' style='background-color: rgba(0,49,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,41,8,1)'></td>
+ <td width='1' style='background-color: rgba(197,41,16,1)'></td>
+ <td width='1' style='background-color: rgba(189,41,25,1)'></td>
+ <td width='1' style='background-color: rgba(181,41,33,1)'></td>
+ <td width='1' style='background-color: rgba(173,41,41,1)'></td>
+ <td width='1' style='background-color: rgba(165,41,49,1)'></td>
+ <td width='1' style='background-color: rgba(156,41,58,1)'></td>
+ <td width='1' style='background-color: rgba(148,41,66,1)'></td>
+ <td width='1' style='background-color: rgba(140,41,74,1)'></td>
+ <td width='1' style='background-color: rgba(132,41,82,1)'></td>
+ <td width='1' style='background-color: rgba(123,41,90,1)'></td>
+ <td width='1' style='background-color: rgba(115,41,99,1)'></td>
+ <td width='1' style='background-color: rgba(107,41,107,1)'></td>
+ <td width='1' style='background-color: rgba(99,41,115,1)'></td>
+ <td width='1' style='background-color: rgba(90,41,123,1)'></td>
+ <td width='1' style='background-color: rgba(82,41,132,1)'></td>
+ <td width='1' style='background-color: rgba(74,41,140,1)'></td>
+ <td width='1' style='background-color: rgba(66,41,148,1)'></td>
+ <td width='1' style='background-color: rgba(58,41,156,1)'></td>
+ <td width='1' style='background-color: rgba(49,41,165,1)'></td>
+ <td width='1' style='background-color: rgba(41,41,173,1)'></td>
+ <td width='1' style='background-color: rgba(33,41,181,1)'></td>
+ <td width='1' style='background-color: rgba(25,41,189,1)'></td>
+ <td width='1' style='background-color: rgba(16,41,197,1)'></td>
+ <td width='1' style='background-color: rgba(8,41,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,41,214,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,33,8,1)'></td>
+ <td width='1' style='background-color: rgba(206,33,16,1)'></td>
+ <td width='1' style='background-color: rgba(197,33,25,1)'></td>
+ <td width='1' style='background-color: rgba(189,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(181,33,41,1)'></td>
+ <td width='1' style='background-color: rgba(173,33,49,1)'></td>
+ <td width='1' style='background-color: rgba(165,33,58,1)'></td>
+ <td width='1' style='background-color: rgba(156,33,66,1)'></td>
+ <td width='1' style='background-color: rgba(148,33,74,1)'></td>
+ <td width='1' style='background-color: rgba(140,33,82,1)'></td>
+ <td width='1' style='background-color: rgba(132,33,90,1)'></td>
+ <td width='1' style='background-color: rgba(123,33,99,1)'></td>
+ <td width='1' style='background-color: rgba(115,33,107,1)'></td>
+ <td width='1' style='background-color: rgba(107,33,115,1)'></td>
+ <td width='1' style='background-color: rgba(99,33,123,1)'></td>
+ <td width='1' style='background-color: rgba(90,33,132,1)'></td>
+ <td width='1' style='background-color: rgba(82,33,140,1)'></td>
+ <td width='1' style='background-color: rgba(74,33,148,1)'></td>
+ <td width='1' style='background-color: rgba(66,33,156,1)'></td>
+ <td width='1' style='background-color: rgba(58,33,165,1)'></td>
+ <td width='1' style='background-color: rgba(49,33,173,1)'></td>
+ <td width='1' style='background-color: rgba(41,33,181,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,189,1)'></td>
+ <td width='1' style='background-color: rgba(25,33,197,1)'></td>
+ <td width='1' style='background-color: rgba(16,33,206,1)'></td>
+ <td width='1' style='background-color: rgba(8,33,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,222,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,25,8,1)'></td>
+ <td width='1' style='background-color: rgba(214,25,16,1)'></td>
+ <td width='1' style='background-color: rgba(206,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(197,25,33,1)'></td>
+ <td width='1' style='background-color: rgba(189,25,41,1)'></td>
+ <td width='1' style='background-color: rgba(181,25,49,1)'></td>
+ <td width='1' style='background-color: rgba(173,25,58,1)'></td>
+ <td width='1' style='background-color: rgba(165,25,66,1)'></td>
+ <td width='1' style='background-color: rgba(156,25,74,1)'></td>
+ <td width='1' style='background-color: rgba(148,25,82,1)'></td>
+ <td width='1' style='background-color: rgba(140,25,90,1)'></td>
+ <td width='1' style='background-color: rgba(132,25,99,1)'></td>
+ <td width='1' style='background-color: rgba(123,25,107,1)'></td>
+ <td width='1' style='background-color: rgba(115,25,115,1)'></td>
+ <td width='1' style='background-color: rgba(107,25,123,1)'></td>
+ <td width='1' style='background-color: rgba(99,25,132,1)'></td>
+ <td width='1' style='background-color: rgba(90,25,140,1)'></td>
+ <td width='1' style='background-color: rgba(82,25,148,1)'></td>
+ <td width='1' style='background-color: rgba(74,25,156,1)'></td>
+ <td width='1' style='background-color: rgba(66,25,165,1)'></td>
+ <td width='1' style='background-color: rgba(58,25,173,1)'></td>
+ <td width='1' style='background-color: rgba(49,25,181,1)'></td>
+ <td width='1' style='background-color: rgba(41,25,189,1)'></td>
+ <td width='1' style='background-color: rgba(33,25,197,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,206,1)'></td>
+ <td width='1' style='background-color: rgba(16,25,214,1)'></td>
+ <td width='1' style='background-color: rgba(8,25,222,1)'></td>
+ <td width='1' style='background-color: rgba(0,25,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,16,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,16,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,16,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,16,8,1)'></td>
+ <td width='1' style='background-color: rgba(222,16,16,1)'></td>
+ <td width='1' style='background-color: rgba(214,16,25,1)'></td>
+ <td width='1' style='background-color: rgba(206,16,33,1)'></td>
+ <td width='1' style='background-color: rgba(197,16,41,1)'></td>
+ <td width='1' style='background-color: rgba(189,16,49,1)'></td>
+ <td width='1' style='background-color: rgba(181,16,58,1)'></td>
+ <td width='1' style='background-color: rgba(173,16,66,1)'></td>
+ <td width='1' style='background-color: rgba(165,16,74,1)'></td>
+ <td width='1' style='background-color: rgba(156,16,82,1)'></td>
+ <td width='1' style='background-color: rgba(148,16,90,1)'></td>
+ <td width='1' style='background-color: rgba(140,16,99,1)'></td>
+ <td width='1' style='background-color: rgba(132,16,107,1)'></td>
+ <td width='1' style='background-color: rgba(123,16,115,1)'></td>
+ <td width='1' style='background-color: rgba(115,16,123,1)'></td>
+ <td width='1' style='background-color: rgba(107,16,132,1)'></td>
+ <td width='1' style='background-color: rgba(99,16,140,1)'></td>
+ <td width='1' style='background-color: rgba(90,16,148,1)'></td>
+ <td width='1' style='background-color: rgba(82,16,156,1)'></td>
+ <td width='1' style='background-color: rgba(74,16,165,1)'></td>
+ <td width='1' style='background-color: rgba(66,16,173,1)'></td>
+ <td width='1' style='background-color: rgba(58,16,181,1)'></td>
+ <td width='1' style='background-color: rgba(49,16,189,1)'></td>
+ <td width='1' style='background-color: rgba(41,16,197,1)'></td>
+ <td width='1' style='background-color: rgba(33,16,206,1)'></td>
+ <td width='1' style='background-color: rgba(25,16,214,1)'></td>
+ <td width='1' style='background-color: rgba(16,16,222,1)'></td>
+ <td width='1' style='background-color: rgba(8,16,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,8,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,8,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(230,8,16,1)'></td>
+ <td width='1' style='background-color: rgba(222,8,25,1)'></td>
+ <td width='1' style='background-color: rgba(214,8,33,1)'></td>
+ <td width='1' style='background-color: rgba(206,8,41,1)'></td>
+ <td width='1' style='background-color: rgba(197,8,49,1)'></td>
+ <td width='1' style='background-color: rgba(189,8,58,1)'></td>
+ <td width='1' style='background-color: rgba(181,8,66,1)'></td>
+ <td width='1' style='background-color: rgba(173,8,74,1)'></td>
+ <td width='1' style='background-color: rgba(165,8,82,1)'></td>
+ <td width='1' style='background-color: rgba(156,8,90,1)'></td>
+ <td width='1' style='background-color: rgba(148,8,99,1)'></td>
+ <td width='1' style='background-color: rgba(140,8,107,1)'></td>
+ <td width='1' style='background-color: rgba(132,8,115,1)'></td>
+ <td width='1' style='background-color: rgba(123,8,123,1)'></td>
+ <td width='1' style='background-color: rgba(115,8,132,1)'></td>
+ <td width='1' style='background-color: rgba(107,8,140,1)'></td>
+ <td width='1' style='background-color: rgba(99,8,148,1)'></td>
+ <td width='1' style='background-color: rgba(90,8,156,1)'></td>
+ <td width='1' style='background-color: rgba(82,8,165,1)'></td>
+ <td width='1' style='background-color: rgba(74,8,173,1)'></td>
+ <td width='1' style='background-color: rgba(66,8,181,1)'></td>
+ <td width='1' style='background-color: rgba(58,8,189,1)'></td>
+ <td width='1' style='background-color: rgba(49,8,197,1)'></td>
+ <td width='1' style='background-color: rgba(41,8,206,1)'></td>
+ <td width='1' style='background-color: rgba(33,8,214,1)'></td>
+ <td width='1' style='background-color: rgba(25,8,222,1)'></td>
+ <td width='1' style='background-color: rgba(16,8,230,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,8,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,16,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,25,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,33,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,41,1)'></td>
+ <td width='1' style='background-color: rgba(206,0,49,1)'></td>
+ <td width='1' style='background-color: rgba(197,0,58,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,66,1)'></td>
+ <td width='1' style='background-color: rgba(181,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(173,0,82,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,90,1)'></td>
+ <td width='1' style='background-color: rgba(156,0,99,1)'></td>
+ <td width='1' style='background-color: rgba(148,0,107,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,115,1)'></td>
+ <td width='1' style='background-color: rgba(132,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,132,1)'></td>
+ <td width='1' style='background-color: rgba(115,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(107,0,148,1)'></td>
+ <td width='1' style='background-color: rgba(99,0,156,1)'></td>
+ <td width='1' style='background-color: rgba(90,0,165,1)'></td>
+ <td width='1' style='background-color: rgba(82,0,173,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,181,1)'></td>
+ <td width='1' style='background-color: rgba(66,0,189,1)'></td>
+ <td width='1' style='background-color: rgba(58,0,197,1)'></td>
+ <td width='1' style='background-color: rgba(49,0,206,1)'></td>
+ <td width='1' style='background-color: rgba(41,0,214,1)'></td>
+ <td width='1' style='background-color: rgba(33,0,222,1)'></td>
+ <td width='1' style='background-color: rgba(25,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(16,0,239,1)'></td>
+ <td width='1' style='background-color: rgba(8,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-zlib/z00n2c08.png b/image/test/reftest/pngsuite-zlib/z00n2c08.png
new file mode 100644
index 0000000000..7669eb8385
--- /dev/null
+++ b/image/test/reftest/pngsuite-zlib/z00n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-zlib/z03n2c08.html b/image/test/reftest/pngsuite-zlib/z03n2c08.html
new file mode 100644
index 0000000000..c878a03ff6
--- /dev/null
+++ b/image/test/reftest/pngsuite-zlib/z03n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(8,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(8,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,8,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(8,239,8,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,16,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,230,8,1)'></td>
+ <td width='1' style='background-color: rgba(8,230,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,25,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,222,8,1)'></td>
+ <td width='1' style='background-color: rgba(16,222,16,1)'></td>
+ <td width='1' style='background-color: rgba(8,222,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,222,33,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,214,8,1)'></td>
+ <td width='1' style='background-color: rgba(25,214,16,1)'></td>
+ <td width='1' style='background-color: rgba(16,214,25,1)'></td>
+ <td width='1' style='background-color: rgba(8,214,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,214,41,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,206,8,1)'></td>
+ <td width='1' style='background-color: rgba(33,206,16,1)'></td>
+ <td width='1' style='background-color: rgba(25,206,25,1)'></td>
+ <td width='1' style='background-color: rgba(16,206,33,1)'></td>
+ <td width='1' style='background-color: rgba(8,206,41,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,49,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,197,8,1)'></td>
+ <td width='1' style='background-color: rgba(41,197,16,1)'></td>
+ <td width='1' style='background-color: rgba(33,197,25,1)'></td>
+ <td width='1' style='background-color: rgba(25,197,33,1)'></td>
+ <td width='1' style='background-color: rgba(16,197,41,1)'></td>
+ <td width='1' style='background-color: rgba(8,197,49,1)'></td>
+ <td width='1' style='background-color: rgba(0,197,58,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,189,8,1)'></td>
+ <td width='1' style='background-color: rgba(49,189,16,1)'></td>
+ <td width='1' style='background-color: rgba(41,189,25,1)'></td>
+ <td width='1' style='background-color: rgba(33,189,33,1)'></td>
+ <td width='1' style='background-color: rgba(25,189,41,1)'></td>
+ <td width='1' style='background-color: rgba(16,189,49,1)'></td>
+ <td width='1' style='background-color: rgba(8,189,58,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,66,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,181,8,1)'></td>
+ <td width='1' style='background-color: rgba(58,181,16,1)'></td>
+ <td width='1' style='background-color: rgba(49,181,25,1)'></td>
+ <td width='1' style='background-color: rgba(41,181,33,1)'></td>
+ <td width='1' style='background-color: rgba(33,181,41,1)'></td>
+ <td width='1' style='background-color: rgba(25,181,49,1)'></td>
+ <td width='1' style='background-color: rgba(16,181,58,1)'></td>
+ <td width='1' style='background-color: rgba(8,181,66,1)'></td>
+ <td width='1' style='background-color: rgba(0,181,74,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,173,8,1)'></td>
+ <td width='1' style='background-color: rgba(66,173,16,1)'></td>
+ <td width='1' style='background-color: rgba(58,173,25,1)'></td>
+ <td width='1' style='background-color: rgba(49,173,33,1)'></td>
+ <td width='1' style='background-color: rgba(41,173,41,1)'></td>
+ <td width='1' style='background-color: rgba(33,173,49,1)'></td>
+ <td width='1' style='background-color: rgba(25,173,58,1)'></td>
+ <td width='1' style='background-color: rgba(16,173,66,1)'></td>
+ <td width='1' style='background-color: rgba(8,173,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,82,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,165,8,1)'></td>
+ <td width='1' style='background-color: rgba(74,165,16,1)'></td>
+ <td width='1' style='background-color: rgba(66,165,25,1)'></td>
+ <td width='1' style='background-color: rgba(58,165,33,1)'></td>
+ <td width='1' style='background-color: rgba(49,165,41,1)'></td>
+ <td width='1' style='background-color: rgba(41,165,49,1)'></td>
+ <td width='1' style='background-color: rgba(33,165,58,1)'></td>
+ <td width='1' style='background-color: rgba(25,165,66,1)'></td>
+ <td width='1' style='background-color: rgba(16,165,74,1)'></td>
+ <td width='1' style='background-color: rgba(8,165,82,1)'></td>
+ <td width='1' style='background-color: rgba(0,165,90,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,156,8,1)'></td>
+ <td width='1' style='background-color: rgba(82,156,16,1)'></td>
+ <td width='1' style='background-color: rgba(74,156,25,1)'></td>
+ <td width='1' style='background-color: rgba(66,156,33,1)'></td>
+ <td width='1' style='background-color: rgba(58,156,41,1)'></td>
+ <td width='1' style='background-color: rgba(49,156,49,1)'></td>
+ <td width='1' style='background-color: rgba(41,156,58,1)'></td>
+ <td width='1' style='background-color: rgba(33,156,66,1)'></td>
+ <td width='1' style='background-color: rgba(25,156,74,1)'></td>
+ <td width='1' style='background-color: rgba(16,156,82,1)'></td>
+ <td width='1' style='background-color: rgba(8,156,90,1)'></td>
+ <td width='1' style='background-color: rgba(0,156,99,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,148,8,1)'></td>
+ <td width='1' style='background-color: rgba(90,148,16,1)'></td>
+ <td width='1' style='background-color: rgba(82,148,25,1)'></td>
+ <td width='1' style='background-color: rgba(74,148,33,1)'></td>
+ <td width='1' style='background-color: rgba(66,148,41,1)'></td>
+ <td width='1' style='background-color: rgba(58,148,49,1)'></td>
+ <td width='1' style='background-color: rgba(49,148,58,1)'></td>
+ <td width='1' style='background-color: rgba(41,148,66,1)'></td>
+ <td width='1' style='background-color: rgba(33,148,74,1)'></td>
+ <td width='1' style='background-color: rgba(25,148,82,1)'></td>
+ <td width='1' style='background-color: rgba(16,148,90,1)'></td>
+ <td width='1' style='background-color: rgba(8,148,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,148,107,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,140,8,1)'></td>
+ <td width='1' style='background-color: rgba(99,140,16,1)'></td>
+ <td width='1' style='background-color: rgba(90,140,25,1)'></td>
+ <td width='1' style='background-color: rgba(82,140,33,1)'></td>
+ <td width='1' style='background-color: rgba(74,140,41,1)'></td>
+ <td width='1' style='background-color: rgba(66,140,49,1)'></td>
+ <td width='1' style='background-color: rgba(58,140,58,1)'></td>
+ <td width='1' style='background-color: rgba(49,140,66,1)'></td>
+ <td width='1' style='background-color: rgba(41,140,74,1)'></td>
+ <td width='1' style='background-color: rgba(33,140,82,1)'></td>
+ <td width='1' style='background-color: rgba(25,140,90,1)'></td>
+ <td width='1' style='background-color: rgba(16,140,99,1)'></td>
+ <td width='1' style='background-color: rgba(8,140,107,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,115,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,132,8,1)'></td>
+ <td width='1' style='background-color: rgba(107,132,16,1)'></td>
+ <td width='1' style='background-color: rgba(99,132,25,1)'></td>
+ <td width='1' style='background-color: rgba(90,132,33,1)'></td>
+ <td width='1' style='background-color: rgba(82,132,41,1)'></td>
+ <td width='1' style='background-color: rgba(74,132,49,1)'></td>
+ <td width='1' style='background-color: rgba(66,132,58,1)'></td>
+ <td width='1' style='background-color: rgba(58,132,66,1)'></td>
+ <td width='1' style='background-color: rgba(49,132,74,1)'></td>
+ <td width='1' style='background-color: rgba(41,132,82,1)'></td>
+ <td width='1' style='background-color: rgba(33,132,90,1)'></td>
+ <td width='1' style='background-color: rgba(25,132,99,1)'></td>
+ <td width='1' style='background-color: rgba(16,132,107,1)'></td>
+ <td width='1' style='background-color: rgba(8,132,115,1)'></td>
+ <td width='1' style='background-color: rgba(0,132,123,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,8,1)'></td>
+ <td width='1' style='background-color: rgba(115,123,16,1)'></td>
+ <td width='1' style='background-color: rgba(107,123,25,1)'></td>
+ <td width='1' style='background-color: rgba(99,123,33,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,41,1)'></td>
+ <td width='1' style='background-color: rgba(82,123,49,1)'></td>
+ <td width='1' style='background-color: rgba(74,123,58,1)'></td>
+ <td width='1' style='background-color: rgba(66,123,66,1)'></td>
+ <td width='1' style='background-color: rgba(58,123,74,1)'></td>
+ <td width='1' style='background-color: rgba(49,123,82,1)'></td>
+ <td width='1' style='background-color: rgba(41,123,90,1)'></td>
+ <td width='1' style='background-color: rgba(33,123,99,1)'></td>
+ <td width='1' style='background-color: rgba(25,123,107,1)'></td>
+ <td width='1' style='background-color: rgba(16,123,115,1)'></td>
+ <td width='1' style='background-color: rgba(8,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,132,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,115,8,1)'></td>
+ <td width='1' style='background-color: rgba(123,115,16,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,25,1)'></td>
+ <td width='1' style='background-color: rgba(107,115,33,1)'></td>
+ <td width='1' style='background-color: rgba(99,115,41,1)'></td>
+ <td width='1' style='background-color: rgba(90,115,49,1)'></td>
+ <td width='1' style='background-color: rgba(82,115,58,1)'></td>
+ <td width='1' style='background-color: rgba(74,115,66,1)'></td>
+ <td width='1' style='background-color: rgba(66,115,74,1)'></td>
+ <td width='1' style='background-color: rgba(58,115,82,1)'></td>
+ <td width='1' style='background-color: rgba(49,115,90,1)'></td>
+ <td width='1' style='background-color: rgba(41,115,99,1)'></td>
+ <td width='1' style='background-color: rgba(33,115,107,1)'></td>
+ <td width='1' style='background-color: rgba(25,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(16,115,123,1)'></td>
+ <td width='1' style='background-color: rgba(8,115,132,1)'></td>
+ <td width='1' style='background-color: rgba(0,115,140,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,107,8,1)'></td>
+ <td width='1' style='background-color: rgba(132,107,16,1)'></td>
+ <td width='1' style='background-color: rgba(123,107,25,1)'></td>
+ <td width='1' style='background-color: rgba(115,107,33,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,41,1)'></td>
+ <td width='1' style='background-color: rgba(99,107,49,1)'></td>
+ <td width='1' style='background-color: rgba(90,107,58,1)'></td>
+ <td width='1' style='background-color: rgba(82,107,66,1)'></td>
+ <td width='1' style='background-color: rgba(74,107,74,1)'></td>
+ <td width='1' style='background-color: rgba(66,107,82,1)'></td>
+ <td width='1' style='background-color: rgba(58,107,90,1)'></td>
+ <td width='1' style='background-color: rgba(49,107,99,1)'></td>
+ <td width='1' style='background-color: rgba(41,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(33,107,115,1)'></td>
+ <td width='1' style='background-color: rgba(25,107,123,1)'></td>
+ <td width='1' style='background-color: rgba(16,107,132,1)'></td>
+ <td width='1' style='background-color: rgba(8,107,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,107,148,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,99,8,1)'></td>
+ <td width='1' style='background-color: rgba(140,99,16,1)'></td>
+ <td width='1' style='background-color: rgba(132,99,25,1)'></td>
+ <td width='1' style='background-color: rgba(123,99,33,1)'></td>
+ <td width='1' style='background-color: rgba(115,99,41,1)'></td>
+ <td width='1' style='background-color: rgba(107,99,49,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,58,1)'></td>
+ <td width='1' style='background-color: rgba(90,99,66,1)'></td>
+ <td width='1' style='background-color: rgba(82,99,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,99,82,1)'></td>
+ <td width='1' style='background-color: rgba(66,99,90,1)'></td>
+ <td width='1' style='background-color: rgba(58,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(49,99,107,1)'></td>
+ <td width='1' style='background-color: rgba(41,99,115,1)'></td>
+ <td width='1' style='background-color: rgba(33,99,123,1)'></td>
+ <td width='1' style='background-color: rgba(25,99,132,1)'></td>
+ <td width='1' style='background-color: rgba(16,99,140,1)'></td>
+ <td width='1' style='background-color: rgba(8,99,148,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,156,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,90,8,1)'></td>
+ <td width='1' style='background-color: rgba(148,90,16,1)'></td>
+ <td width='1' style='background-color: rgba(140,90,25,1)'></td>
+ <td width='1' style='background-color: rgba(132,90,33,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,41,1)'></td>
+ <td width='1' style='background-color: rgba(115,90,49,1)'></td>
+ <td width='1' style='background-color: rgba(107,90,58,1)'></td>
+ <td width='1' style='background-color: rgba(99,90,66,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,74,1)'></td>
+ <td width='1' style='background-color: rgba(82,90,82,1)'></td>
+ <td width='1' style='background-color: rgba(74,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(66,90,99,1)'></td>
+ <td width='1' style='background-color: rgba(58,90,107,1)'></td>
+ <td width='1' style='background-color: rgba(49,90,115,1)'></td>
+ <td width='1' style='background-color: rgba(41,90,123,1)'></td>
+ <td width='1' style='background-color: rgba(33,90,132,1)'></td>
+ <td width='1' style='background-color: rgba(25,90,140,1)'></td>
+ <td width='1' style='background-color: rgba(16,90,148,1)'></td>
+ <td width='1' style='background-color: rgba(8,90,156,1)'></td>
+ <td width='1' style='background-color: rgba(0,90,165,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,82,8,1)'></td>
+ <td width='1' style='background-color: rgba(156,82,16,1)'></td>
+ <td width='1' style='background-color: rgba(148,82,25,1)'></td>
+ <td width='1' style='background-color: rgba(140,82,33,1)'></td>
+ <td width='1' style='background-color: rgba(132,82,41,1)'></td>
+ <td width='1' style='background-color: rgba(123,82,49,1)'></td>
+ <td width='1' style='background-color: rgba(115,82,58,1)'></td>
+ <td width='1' style='background-color: rgba(107,82,66,1)'></td>
+ <td width='1' style='background-color: rgba(99,82,74,1)'></td>
+ <td width='1' style='background-color: rgba(90,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,90,1)'></td>
+ <td width='1' style='background-color: rgba(74,82,99,1)'></td>
+ <td width='1' style='background-color: rgba(66,82,107,1)'></td>
+ <td width='1' style='background-color: rgba(58,82,115,1)'></td>
+ <td width='1' style='background-color: rgba(49,82,123,1)'></td>
+ <td width='1' style='background-color: rgba(41,82,132,1)'></td>
+ <td width='1' style='background-color: rgba(33,82,140,1)'></td>
+ <td width='1' style='background-color: rgba(25,82,148,1)'></td>
+ <td width='1' style='background-color: rgba(16,82,156,1)'></td>
+ <td width='1' style='background-color: rgba(8,82,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,82,173,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,74,8,1)'></td>
+ <td width='1' style='background-color: rgba(165,74,16,1)'></td>
+ <td width='1' style='background-color: rgba(156,74,25,1)'></td>
+ <td width='1' style='background-color: rgba(148,74,33,1)'></td>
+ <td width='1' style='background-color: rgba(140,74,41,1)'></td>
+ <td width='1' style='background-color: rgba(132,74,49,1)'></td>
+ <td width='1' style='background-color: rgba(123,74,58,1)'></td>
+ <td width='1' style='background-color: rgba(115,74,66,1)'></td>
+ <td width='1' style='background-color: rgba(107,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(99,74,82,1)'></td>
+ <td width='1' style='background-color: rgba(90,74,90,1)'></td>
+ <td width='1' style='background-color: rgba(82,74,99,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,107,1)'></td>
+ <td width='1' style='background-color: rgba(66,74,115,1)'></td>
+ <td width='1' style='background-color: rgba(58,74,123,1)'></td>
+ <td width='1' style='background-color: rgba(49,74,132,1)'></td>
+ <td width='1' style='background-color: rgba(41,74,140,1)'></td>
+ <td width='1' style='background-color: rgba(33,74,148,1)'></td>
+ <td width='1' style='background-color: rgba(25,74,156,1)'></td>
+ <td width='1' style='background-color: rgba(16,74,165,1)'></td>
+ <td width='1' style='background-color: rgba(8,74,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,181,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,66,8,1)'></td>
+ <td width='1' style='background-color: rgba(173,66,16,1)'></td>
+ <td width='1' style='background-color: rgba(165,66,25,1)'></td>
+ <td width='1' style='background-color: rgba(156,66,33,1)'></td>
+ <td width='1' style='background-color: rgba(148,66,41,1)'></td>
+ <td width='1' style='background-color: rgba(140,66,49,1)'></td>
+ <td width='1' style='background-color: rgba(132,66,58,1)'></td>
+ <td width='1' style='background-color: rgba(123,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(115,66,74,1)'></td>
+ <td width='1' style='background-color: rgba(107,66,82,1)'></td>
+ <td width='1' style='background-color: rgba(99,66,90,1)'></td>
+ <td width='1' style='background-color: rgba(90,66,99,1)'></td>
+ <td width='1' style='background-color: rgba(82,66,107,1)'></td>
+ <td width='1' style='background-color: rgba(74,66,115,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,123,1)'></td>
+ <td width='1' style='background-color: rgba(58,66,132,1)'></td>
+ <td width='1' style='background-color: rgba(49,66,140,1)'></td>
+ <td width='1' style='background-color: rgba(41,66,148,1)'></td>
+ <td width='1' style='background-color: rgba(33,66,156,1)'></td>
+ <td width='1' style='background-color: rgba(25,66,165,1)'></td>
+ <td width='1' style='background-color: rgba(16,66,173,1)'></td>
+ <td width='1' style='background-color: rgba(8,66,181,1)'></td>
+ <td width='1' style='background-color: rgba(0,66,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,58,8,1)'></td>
+ <td width='1' style='background-color: rgba(181,58,16,1)'></td>
+ <td width='1' style='background-color: rgba(173,58,25,1)'></td>
+ <td width='1' style='background-color: rgba(165,58,33,1)'></td>
+ <td width='1' style='background-color: rgba(156,58,41,1)'></td>
+ <td width='1' style='background-color: rgba(148,58,49,1)'></td>
+ <td width='1' style='background-color: rgba(140,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(132,58,66,1)'></td>
+ <td width='1' style='background-color: rgba(123,58,74,1)'></td>
+ <td width='1' style='background-color: rgba(115,58,82,1)'></td>
+ <td width='1' style='background-color: rgba(107,58,90,1)'></td>
+ <td width='1' style='background-color: rgba(99,58,99,1)'></td>
+ <td width='1' style='background-color: rgba(90,58,107,1)'></td>
+ <td width='1' style='background-color: rgba(82,58,115,1)'></td>
+ <td width='1' style='background-color: rgba(74,58,123,1)'></td>
+ <td width='1' style='background-color: rgba(66,58,132,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,140,1)'></td>
+ <td width='1' style='background-color: rgba(49,58,148,1)'></td>
+ <td width='1' style='background-color: rgba(41,58,156,1)'></td>
+ <td width='1' style='background-color: rgba(33,58,165,1)'></td>
+ <td width='1' style='background-color: rgba(25,58,173,1)'></td>
+ <td width='1' style='background-color: rgba(16,58,181,1)'></td>
+ <td width='1' style='background-color: rgba(8,58,189,1)'></td>
+ <td width='1' style='background-color: rgba(0,58,197,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,49,8,1)'></td>
+ <td width='1' style='background-color: rgba(189,49,16,1)'></td>
+ <td width='1' style='background-color: rgba(181,49,25,1)'></td>
+ <td width='1' style='background-color: rgba(173,49,33,1)'></td>
+ <td width='1' style='background-color: rgba(165,49,41,1)'></td>
+ <td width='1' style='background-color: rgba(156,49,49,1)'></td>
+ <td width='1' style='background-color: rgba(148,49,58,1)'></td>
+ <td width='1' style='background-color: rgba(140,49,66,1)'></td>
+ <td width='1' style='background-color: rgba(132,49,74,1)'></td>
+ <td width='1' style='background-color: rgba(123,49,82,1)'></td>
+ <td width='1' style='background-color: rgba(115,49,90,1)'></td>
+ <td width='1' style='background-color: rgba(107,49,99,1)'></td>
+ <td width='1' style='background-color: rgba(99,49,107,1)'></td>
+ <td width='1' style='background-color: rgba(90,49,115,1)'></td>
+ <td width='1' style='background-color: rgba(82,49,123,1)'></td>
+ <td width='1' style='background-color: rgba(74,49,132,1)'></td>
+ <td width='1' style='background-color: rgba(66,49,140,1)'></td>
+ <td width='1' style='background-color: rgba(58,49,148,1)'></td>
+ <td width='1' style='background-color: rgba(49,49,156,1)'></td>
+ <td width='1' style='background-color: rgba(41,49,165,1)'></td>
+ <td width='1' style='background-color: rgba(33,49,173,1)'></td>
+ <td width='1' style='background-color: rgba(25,49,181,1)'></td>
+ <td width='1' style='background-color: rgba(16,49,189,1)'></td>
+ <td width='1' style='background-color: rgba(8,49,197,1)'></td>
+ <td width='1' style='background-color: rgba(0,49,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,41,8,1)'></td>
+ <td width='1' style='background-color: rgba(197,41,16,1)'></td>
+ <td width='1' style='background-color: rgba(189,41,25,1)'></td>
+ <td width='1' style='background-color: rgba(181,41,33,1)'></td>
+ <td width='1' style='background-color: rgba(173,41,41,1)'></td>
+ <td width='1' style='background-color: rgba(165,41,49,1)'></td>
+ <td width='1' style='background-color: rgba(156,41,58,1)'></td>
+ <td width='1' style='background-color: rgba(148,41,66,1)'></td>
+ <td width='1' style='background-color: rgba(140,41,74,1)'></td>
+ <td width='1' style='background-color: rgba(132,41,82,1)'></td>
+ <td width='1' style='background-color: rgba(123,41,90,1)'></td>
+ <td width='1' style='background-color: rgba(115,41,99,1)'></td>
+ <td width='1' style='background-color: rgba(107,41,107,1)'></td>
+ <td width='1' style='background-color: rgba(99,41,115,1)'></td>
+ <td width='1' style='background-color: rgba(90,41,123,1)'></td>
+ <td width='1' style='background-color: rgba(82,41,132,1)'></td>
+ <td width='1' style='background-color: rgba(74,41,140,1)'></td>
+ <td width='1' style='background-color: rgba(66,41,148,1)'></td>
+ <td width='1' style='background-color: rgba(58,41,156,1)'></td>
+ <td width='1' style='background-color: rgba(49,41,165,1)'></td>
+ <td width='1' style='background-color: rgba(41,41,173,1)'></td>
+ <td width='1' style='background-color: rgba(33,41,181,1)'></td>
+ <td width='1' style='background-color: rgba(25,41,189,1)'></td>
+ <td width='1' style='background-color: rgba(16,41,197,1)'></td>
+ <td width='1' style='background-color: rgba(8,41,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,41,214,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,33,8,1)'></td>
+ <td width='1' style='background-color: rgba(206,33,16,1)'></td>
+ <td width='1' style='background-color: rgba(197,33,25,1)'></td>
+ <td width='1' style='background-color: rgba(189,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(181,33,41,1)'></td>
+ <td width='1' style='background-color: rgba(173,33,49,1)'></td>
+ <td width='1' style='background-color: rgba(165,33,58,1)'></td>
+ <td width='1' style='background-color: rgba(156,33,66,1)'></td>
+ <td width='1' style='background-color: rgba(148,33,74,1)'></td>
+ <td width='1' style='background-color: rgba(140,33,82,1)'></td>
+ <td width='1' style='background-color: rgba(132,33,90,1)'></td>
+ <td width='1' style='background-color: rgba(123,33,99,1)'></td>
+ <td width='1' style='background-color: rgba(115,33,107,1)'></td>
+ <td width='1' style='background-color: rgba(107,33,115,1)'></td>
+ <td width='1' style='background-color: rgba(99,33,123,1)'></td>
+ <td width='1' style='background-color: rgba(90,33,132,1)'></td>
+ <td width='1' style='background-color: rgba(82,33,140,1)'></td>
+ <td width='1' style='background-color: rgba(74,33,148,1)'></td>
+ <td width='1' style='background-color: rgba(66,33,156,1)'></td>
+ <td width='1' style='background-color: rgba(58,33,165,1)'></td>
+ <td width='1' style='background-color: rgba(49,33,173,1)'></td>
+ <td width='1' style='background-color: rgba(41,33,181,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,189,1)'></td>
+ <td width='1' style='background-color: rgba(25,33,197,1)'></td>
+ <td width='1' style='background-color: rgba(16,33,206,1)'></td>
+ <td width='1' style='background-color: rgba(8,33,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,222,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,25,8,1)'></td>
+ <td width='1' style='background-color: rgba(214,25,16,1)'></td>
+ <td width='1' style='background-color: rgba(206,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(197,25,33,1)'></td>
+ <td width='1' style='background-color: rgba(189,25,41,1)'></td>
+ <td width='1' style='background-color: rgba(181,25,49,1)'></td>
+ <td width='1' style='background-color: rgba(173,25,58,1)'></td>
+ <td width='1' style='background-color: rgba(165,25,66,1)'></td>
+ <td width='1' style='background-color: rgba(156,25,74,1)'></td>
+ <td width='1' style='background-color: rgba(148,25,82,1)'></td>
+ <td width='1' style='background-color: rgba(140,25,90,1)'></td>
+ <td width='1' style='background-color: rgba(132,25,99,1)'></td>
+ <td width='1' style='background-color: rgba(123,25,107,1)'></td>
+ <td width='1' style='background-color: rgba(115,25,115,1)'></td>
+ <td width='1' style='background-color: rgba(107,25,123,1)'></td>
+ <td width='1' style='background-color: rgba(99,25,132,1)'></td>
+ <td width='1' style='background-color: rgba(90,25,140,1)'></td>
+ <td width='1' style='background-color: rgba(82,25,148,1)'></td>
+ <td width='1' style='background-color: rgba(74,25,156,1)'></td>
+ <td width='1' style='background-color: rgba(66,25,165,1)'></td>
+ <td width='1' style='background-color: rgba(58,25,173,1)'></td>
+ <td width='1' style='background-color: rgba(49,25,181,1)'></td>
+ <td width='1' style='background-color: rgba(41,25,189,1)'></td>
+ <td width='1' style='background-color: rgba(33,25,197,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,206,1)'></td>
+ <td width='1' style='background-color: rgba(16,25,214,1)'></td>
+ <td width='1' style='background-color: rgba(8,25,222,1)'></td>
+ <td width='1' style='background-color: rgba(0,25,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,16,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,16,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,16,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,16,8,1)'></td>
+ <td width='1' style='background-color: rgba(222,16,16,1)'></td>
+ <td width='1' style='background-color: rgba(214,16,25,1)'></td>
+ <td width='1' style='background-color: rgba(206,16,33,1)'></td>
+ <td width='1' style='background-color: rgba(197,16,41,1)'></td>
+ <td width='1' style='background-color: rgba(189,16,49,1)'></td>
+ <td width='1' style='background-color: rgba(181,16,58,1)'></td>
+ <td width='1' style='background-color: rgba(173,16,66,1)'></td>
+ <td width='1' style='background-color: rgba(165,16,74,1)'></td>
+ <td width='1' style='background-color: rgba(156,16,82,1)'></td>
+ <td width='1' style='background-color: rgba(148,16,90,1)'></td>
+ <td width='1' style='background-color: rgba(140,16,99,1)'></td>
+ <td width='1' style='background-color: rgba(132,16,107,1)'></td>
+ <td width='1' style='background-color: rgba(123,16,115,1)'></td>
+ <td width='1' style='background-color: rgba(115,16,123,1)'></td>
+ <td width='1' style='background-color: rgba(107,16,132,1)'></td>
+ <td width='1' style='background-color: rgba(99,16,140,1)'></td>
+ <td width='1' style='background-color: rgba(90,16,148,1)'></td>
+ <td width='1' style='background-color: rgba(82,16,156,1)'></td>
+ <td width='1' style='background-color: rgba(74,16,165,1)'></td>
+ <td width='1' style='background-color: rgba(66,16,173,1)'></td>
+ <td width='1' style='background-color: rgba(58,16,181,1)'></td>
+ <td width='1' style='background-color: rgba(49,16,189,1)'></td>
+ <td width='1' style='background-color: rgba(41,16,197,1)'></td>
+ <td width='1' style='background-color: rgba(33,16,206,1)'></td>
+ <td width='1' style='background-color: rgba(25,16,214,1)'></td>
+ <td width='1' style='background-color: rgba(16,16,222,1)'></td>
+ <td width='1' style='background-color: rgba(8,16,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,8,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,8,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(230,8,16,1)'></td>
+ <td width='1' style='background-color: rgba(222,8,25,1)'></td>
+ <td width='1' style='background-color: rgba(214,8,33,1)'></td>
+ <td width='1' style='background-color: rgba(206,8,41,1)'></td>
+ <td width='1' style='background-color: rgba(197,8,49,1)'></td>
+ <td width='1' style='background-color: rgba(189,8,58,1)'></td>
+ <td width='1' style='background-color: rgba(181,8,66,1)'></td>
+ <td width='1' style='background-color: rgba(173,8,74,1)'></td>
+ <td width='1' style='background-color: rgba(165,8,82,1)'></td>
+ <td width='1' style='background-color: rgba(156,8,90,1)'></td>
+ <td width='1' style='background-color: rgba(148,8,99,1)'></td>
+ <td width='1' style='background-color: rgba(140,8,107,1)'></td>
+ <td width='1' style='background-color: rgba(132,8,115,1)'></td>
+ <td width='1' style='background-color: rgba(123,8,123,1)'></td>
+ <td width='1' style='background-color: rgba(115,8,132,1)'></td>
+ <td width='1' style='background-color: rgba(107,8,140,1)'></td>
+ <td width='1' style='background-color: rgba(99,8,148,1)'></td>
+ <td width='1' style='background-color: rgba(90,8,156,1)'></td>
+ <td width='1' style='background-color: rgba(82,8,165,1)'></td>
+ <td width='1' style='background-color: rgba(74,8,173,1)'></td>
+ <td width='1' style='background-color: rgba(66,8,181,1)'></td>
+ <td width='1' style='background-color: rgba(58,8,189,1)'></td>
+ <td width='1' style='background-color: rgba(49,8,197,1)'></td>
+ <td width='1' style='background-color: rgba(41,8,206,1)'></td>
+ <td width='1' style='background-color: rgba(33,8,214,1)'></td>
+ <td width='1' style='background-color: rgba(25,8,222,1)'></td>
+ <td width='1' style='background-color: rgba(16,8,230,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,8,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,16,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,25,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,33,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,41,1)'></td>
+ <td width='1' style='background-color: rgba(206,0,49,1)'></td>
+ <td width='1' style='background-color: rgba(197,0,58,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,66,1)'></td>
+ <td width='1' style='background-color: rgba(181,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(173,0,82,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,90,1)'></td>
+ <td width='1' style='background-color: rgba(156,0,99,1)'></td>
+ <td width='1' style='background-color: rgba(148,0,107,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,115,1)'></td>
+ <td width='1' style='background-color: rgba(132,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,132,1)'></td>
+ <td width='1' style='background-color: rgba(115,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(107,0,148,1)'></td>
+ <td width='1' style='background-color: rgba(99,0,156,1)'></td>
+ <td width='1' style='background-color: rgba(90,0,165,1)'></td>
+ <td width='1' style='background-color: rgba(82,0,173,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,181,1)'></td>
+ <td width='1' style='background-color: rgba(66,0,189,1)'></td>
+ <td width='1' style='background-color: rgba(58,0,197,1)'></td>
+ <td width='1' style='background-color: rgba(49,0,206,1)'></td>
+ <td width='1' style='background-color: rgba(41,0,214,1)'></td>
+ <td width='1' style='background-color: rgba(33,0,222,1)'></td>
+ <td width='1' style='background-color: rgba(25,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(16,0,239,1)'></td>
+ <td width='1' style='background-color: rgba(8,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-zlib/z03n2c08.png b/image/test/reftest/pngsuite-zlib/z03n2c08.png
new file mode 100644
index 0000000000..bfb10de8de
--- /dev/null
+++ b/image/test/reftest/pngsuite-zlib/z03n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-zlib/z06n2c08.html b/image/test/reftest/pngsuite-zlib/z06n2c08.html
new file mode 100644
index 0000000000..c878a03ff6
--- /dev/null
+++ b/image/test/reftest/pngsuite-zlib/z06n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(8,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(8,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,8,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(8,239,8,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,16,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,230,8,1)'></td>
+ <td width='1' style='background-color: rgba(8,230,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,25,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,222,8,1)'></td>
+ <td width='1' style='background-color: rgba(16,222,16,1)'></td>
+ <td width='1' style='background-color: rgba(8,222,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,222,33,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,214,8,1)'></td>
+ <td width='1' style='background-color: rgba(25,214,16,1)'></td>
+ <td width='1' style='background-color: rgba(16,214,25,1)'></td>
+ <td width='1' style='background-color: rgba(8,214,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,214,41,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,206,8,1)'></td>
+ <td width='1' style='background-color: rgba(33,206,16,1)'></td>
+ <td width='1' style='background-color: rgba(25,206,25,1)'></td>
+ <td width='1' style='background-color: rgba(16,206,33,1)'></td>
+ <td width='1' style='background-color: rgba(8,206,41,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,49,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,197,8,1)'></td>
+ <td width='1' style='background-color: rgba(41,197,16,1)'></td>
+ <td width='1' style='background-color: rgba(33,197,25,1)'></td>
+ <td width='1' style='background-color: rgba(25,197,33,1)'></td>
+ <td width='1' style='background-color: rgba(16,197,41,1)'></td>
+ <td width='1' style='background-color: rgba(8,197,49,1)'></td>
+ <td width='1' style='background-color: rgba(0,197,58,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,189,8,1)'></td>
+ <td width='1' style='background-color: rgba(49,189,16,1)'></td>
+ <td width='1' style='background-color: rgba(41,189,25,1)'></td>
+ <td width='1' style='background-color: rgba(33,189,33,1)'></td>
+ <td width='1' style='background-color: rgba(25,189,41,1)'></td>
+ <td width='1' style='background-color: rgba(16,189,49,1)'></td>
+ <td width='1' style='background-color: rgba(8,189,58,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,66,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,181,8,1)'></td>
+ <td width='1' style='background-color: rgba(58,181,16,1)'></td>
+ <td width='1' style='background-color: rgba(49,181,25,1)'></td>
+ <td width='1' style='background-color: rgba(41,181,33,1)'></td>
+ <td width='1' style='background-color: rgba(33,181,41,1)'></td>
+ <td width='1' style='background-color: rgba(25,181,49,1)'></td>
+ <td width='1' style='background-color: rgba(16,181,58,1)'></td>
+ <td width='1' style='background-color: rgba(8,181,66,1)'></td>
+ <td width='1' style='background-color: rgba(0,181,74,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,173,8,1)'></td>
+ <td width='1' style='background-color: rgba(66,173,16,1)'></td>
+ <td width='1' style='background-color: rgba(58,173,25,1)'></td>
+ <td width='1' style='background-color: rgba(49,173,33,1)'></td>
+ <td width='1' style='background-color: rgba(41,173,41,1)'></td>
+ <td width='1' style='background-color: rgba(33,173,49,1)'></td>
+ <td width='1' style='background-color: rgba(25,173,58,1)'></td>
+ <td width='1' style='background-color: rgba(16,173,66,1)'></td>
+ <td width='1' style='background-color: rgba(8,173,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,82,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,165,8,1)'></td>
+ <td width='1' style='background-color: rgba(74,165,16,1)'></td>
+ <td width='1' style='background-color: rgba(66,165,25,1)'></td>
+ <td width='1' style='background-color: rgba(58,165,33,1)'></td>
+ <td width='1' style='background-color: rgba(49,165,41,1)'></td>
+ <td width='1' style='background-color: rgba(41,165,49,1)'></td>
+ <td width='1' style='background-color: rgba(33,165,58,1)'></td>
+ <td width='1' style='background-color: rgba(25,165,66,1)'></td>
+ <td width='1' style='background-color: rgba(16,165,74,1)'></td>
+ <td width='1' style='background-color: rgba(8,165,82,1)'></td>
+ <td width='1' style='background-color: rgba(0,165,90,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,156,8,1)'></td>
+ <td width='1' style='background-color: rgba(82,156,16,1)'></td>
+ <td width='1' style='background-color: rgba(74,156,25,1)'></td>
+ <td width='1' style='background-color: rgba(66,156,33,1)'></td>
+ <td width='1' style='background-color: rgba(58,156,41,1)'></td>
+ <td width='1' style='background-color: rgba(49,156,49,1)'></td>
+ <td width='1' style='background-color: rgba(41,156,58,1)'></td>
+ <td width='1' style='background-color: rgba(33,156,66,1)'></td>
+ <td width='1' style='background-color: rgba(25,156,74,1)'></td>
+ <td width='1' style='background-color: rgba(16,156,82,1)'></td>
+ <td width='1' style='background-color: rgba(8,156,90,1)'></td>
+ <td width='1' style='background-color: rgba(0,156,99,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,148,8,1)'></td>
+ <td width='1' style='background-color: rgba(90,148,16,1)'></td>
+ <td width='1' style='background-color: rgba(82,148,25,1)'></td>
+ <td width='1' style='background-color: rgba(74,148,33,1)'></td>
+ <td width='1' style='background-color: rgba(66,148,41,1)'></td>
+ <td width='1' style='background-color: rgba(58,148,49,1)'></td>
+ <td width='1' style='background-color: rgba(49,148,58,1)'></td>
+ <td width='1' style='background-color: rgba(41,148,66,1)'></td>
+ <td width='1' style='background-color: rgba(33,148,74,1)'></td>
+ <td width='1' style='background-color: rgba(25,148,82,1)'></td>
+ <td width='1' style='background-color: rgba(16,148,90,1)'></td>
+ <td width='1' style='background-color: rgba(8,148,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,148,107,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,140,8,1)'></td>
+ <td width='1' style='background-color: rgba(99,140,16,1)'></td>
+ <td width='1' style='background-color: rgba(90,140,25,1)'></td>
+ <td width='1' style='background-color: rgba(82,140,33,1)'></td>
+ <td width='1' style='background-color: rgba(74,140,41,1)'></td>
+ <td width='1' style='background-color: rgba(66,140,49,1)'></td>
+ <td width='1' style='background-color: rgba(58,140,58,1)'></td>
+ <td width='1' style='background-color: rgba(49,140,66,1)'></td>
+ <td width='1' style='background-color: rgba(41,140,74,1)'></td>
+ <td width='1' style='background-color: rgba(33,140,82,1)'></td>
+ <td width='1' style='background-color: rgba(25,140,90,1)'></td>
+ <td width='1' style='background-color: rgba(16,140,99,1)'></td>
+ <td width='1' style='background-color: rgba(8,140,107,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,115,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,132,8,1)'></td>
+ <td width='1' style='background-color: rgba(107,132,16,1)'></td>
+ <td width='1' style='background-color: rgba(99,132,25,1)'></td>
+ <td width='1' style='background-color: rgba(90,132,33,1)'></td>
+ <td width='1' style='background-color: rgba(82,132,41,1)'></td>
+ <td width='1' style='background-color: rgba(74,132,49,1)'></td>
+ <td width='1' style='background-color: rgba(66,132,58,1)'></td>
+ <td width='1' style='background-color: rgba(58,132,66,1)'></td>
+ <td width='1' style='background-color: rgba(49,132,74,1)'></td>
+ <td width='1' style='background-color: rgba(41,132,82,1)'></td>
+ <td width='1' style='background-color: rgba(33,132,90,1)'></td>
+ <td width='1' style='background-color: rgba(25,132,99,1)'></td>
+ <td width='1' style='background-color: rgba(16,132,107,1)'></td>
+ <td width='1' style='background-color: rgba(8,132,115,1)'></td>
+ <td width='1' style='background-color: rgba(0,132,123,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,8,1)'></td>
+ <td width='1' style='background-color: rgba(115,123,16,1)'></td>
+ <td width='1' style='background-color: rgba(107,123,25,1)'></td>
+ <td width='1' style='background-color: rgba(99,123,33,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,41,1)'></td>
+ <td width='1' style='background-color: rgba(82,123,49,1)'></td>
+ <td width='1' style='background-color: rgba(74,123,58,1)'></td>
+ <td width='1' style='background-color: rgba(66,123,66,1)'></td>
+ <td width='1' style='background-color: rgba(58,123,74,1)'></td>
+ <td width='1' style='background-color: rgba(49,123,82,1)'></td>
+ <td width='1' style='background-color: rgba(41,123,90,1)'></td>
+ <td width='1' style='background-color: rgba(33,123,99,1)'></td>
+ <td width='1' style='background-color: rgba(25,123,107,1)'></td>
+ <td width='1' style='background-color: rgba(16,123,115,1)'></td>
+ <td width='1' style='background-color: rgba(8,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,132,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,115,8,1)'></td>
+ <td width='1' style='background-color: rgba(123,115,16,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,25,1)'></td>
+ <td width='1' style='background-color: rgba(107,115,33,1)'></td>
+ <td width='1' style='background-color: rgba(99,115,41,1)'></td>
+ <td width='1' style='background-color: rgba(90,115,49,1)'></td>
+ <td width='1' style='background-color: rgba(82,115,58,1)'></td>
+ <td width='1' style='background-color: rgba(74,115,66,1)'></td>
+ <td width='1' style='background-color: rgba(66,115,74,1)'></td>
+ <td width='1' style='background-color: rgba(58,115,82,1)'></td>
+ <td width='1' style='background-color: rgba(49,115,90,1)'></td>
+ <td width='1' style='background-color: rgba(41,115,99,1)'></td>
+ <td width='1' style='background-color: rgba(33,115,107,1)'></td>
+ <td width='1' style='background-color: rgba(25,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(16,115,123,1)'></td>
+ <td width='1' style='background-color: rgba(8,115,132,1)'></td>
+ <td width='1' style='background-color: rgba(0,115,140,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,107,8,1)'></td>
+ <td width='1' style='background-color: rgba(132,107,16,1)'></td>
+ <td width='1' style='background-color: rgba(123,107,25,1)'></td>
+ <td width='1' style='background-color: rgba(115,107,33,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,41,1)'></td>
+ <td width='1' style='background-color: rgba(99,107,49,1)'></td>
+ <td width='1' style='background-color: rgba(90,107,58,1)'></td>
+ <td width='1' style='background-color: rgba(82,107,66,1)'></td>
+ <td width='1' style='background-color: rgba(74,107,74,1)'></td>
+ <td width='1' style='background-color: rgba(66,107,82,1)'></td>
+ <td width='1' style='background-color: rgba(58,107,90,1)'></td>
+ <td width='1' style='background-color: rgba(49,107,99,1)'></td>
+ <td width='1' style='background-color: rgba(41,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(33,107,115,1)'></td>
+ <td width='1' style='background-color: rgba(25,107,123,1)'></td>
+ <td width='1' style='background-color: rgba(16,107,132,1)'></td>
+ <td width='1' style='background-color: rgba(8,107,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,107,148,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,99,8,1)'></td>
+ <td width='1' style='background-color: rgba(140,99,16,1)'></td>
+ <td width='1' style='background-color: rgba(132,99,25,1)'></td>
+ <td width='1' style='background-color: rgba(123,99,33,1)'></td>
+ <td width='1' style='background-color: rgba(115,99,41,1)'></td>
+ <td width='1' style='background-color: rgba(107,99,49,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,58,1)'></td>
+ <td width='1' style='background-color: rgba(90,99,66,1)'></td>
+ <td width='1' style='background-color: rgba(82,99,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,99,82,1)'></td>
+ <td width='1' style='background-color: rgba(66,99,90,1)'></td>
+ <td width='1' style='background-color: rgba(58,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(49,99,107,1)'></td>
+ <td width='1' style='background-color: rgba(41,99,115,1)'></td>
+ <td width='1' style='background-color: rgba(33,99,123,1)'></td>
+ <td width='1' style='background-color: rgba(25,99,132,1)'></td>
+ <td width='1' style='background-color: rgba(16,99,140,1)'></td>
+ <td width='1' style='background-color: rgba(8,99,148,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,156,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,90,8,1)'></td>
+ <td width='1' style='background-color: rgba(148,90,16,1)'></td>
+ <td width='1' style='background-color: rgba(140,90,25,1)'></td>
+ <td width='1' style='background-color: rgba(132,90,33,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,41,1)'></td>
+ <td width='1' style='background-color: rgba(115,90,49,1)'></td>
+ <td width='1' style='background-color: rgba(107,90,58,1)'></td>
+ <td width='1' style='background-color: rgba(99,90,66,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,74,1)'></td>
+ <td width='1' style='background-color: rgba(82,90,82,1)'></td>
+ <td width='1' style='background-color: rgba(74,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(66,90,99,1)'></td>
+ <td width='1' style='background-color: rgba(58,90,107,1)'></td>
+ <td width='1' style='background-color: rgba(49,90,115,1)'></td>
+ <td width='1' style='background-color: rgba(41,90,123,1)'></td>
+ <td width='1' style='background-color: rgba(33,90,132,1)'></td>
+ <td width='1' style='background-color: rgba(25,90,140,1)'></td>
+ <td width='1' style='background-color: rgba(16,90,148,1)'></td>
+ <td width='1' style='background-color: rgba(8,90,156,1)'></td>
+ <td width='1' style='background-color: rgba(0,90,165,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,82,8,1)'></td>
+ <td width='1' style='background-color: rgba(156,82,16,1)'></td>
+ <td width='1' style='background-color: rgba(148,82,25,1)'></td>
+ <td width='1' style='background-color: rgba(140,82,33,1)'></td>
+ <td width='1' style='background-color: rgba(132,82,41,1)'></td>
+ <td width='1' style='background-color: rgba(123,82,49,1)'></td>
+ <td width='1' style='background-color: rgba(115,82,58,1)'></td>
+ <td width='1' style='background-color: rgba(107,82,66,1)'></td>
+ <td width='1' style='background-color: rgba(99,82,74,1)'></td>
+ <td width='1' style='background-color: rgba(90,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,90,1)'></td>
+ <td width='1' style='background-color: rgba(74,82,99,1)'></td>
+ <td width='1' style='background-color: rgba(66,82,107,1)'></td>
+ <td width='1' style='background-color: rgba(58,82,115,1)'></td>
+ <td width='1' style='background-color: rgba(49,82,123,1)'></td>
+ <td width='1' style='background-color: rgba(41,82,132,1)'></td>
+ <td width='1' style='background-color: rgba(33,82,140,1)'></td>
+ <td width='1' style='background-color: rgba(25,82,148,1)'></td>
+ <td width='1' style='background-color: rgba(16,82,156,1)'></td>
+ <td width='1' style='background-color: rgba(8,82,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,82,173,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,74,8,1)'></td>
+ <td width='1' style='background-color: rgba(165,74,16,1)'></td>
+ <td width='1' style='background-color: rgba(156,74,25,1)'></td>
+ <td width='1' style='background-color: rgba(148,74,33,1)'></td>
+ <td width='1' style='background-color: rgba(140,74,41,1)'></td>
+ <td width='1' style='background-color: rgba(132,74,49,1)'></td>
+ <td width='1' style='background-color: rgba(123,74,58,1)'></td>
+ <td width='1' style='background-color: rgba(115,74,66,1)'></td>
+ <td width='1' style='background-color: rgba(107,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(99,74,82,1)'></td>
+ <td width='1' style='background-color: rgba(90,74,90,1)'></td>
+ <td width='1' style='background-color: rgba(82,74,99,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,107,1)'></td>
+ <td width='1' style='background-color: rgba(66,74,115,1)'></td>
+ <td width='1' style='background-color: rgba(58,74,123,1)'></td>
+ <td width='1' style='background-color: rgba(49,74,132,1)'></td>
+ <td width='1' style='background-color: rgba(41,74,140,1)'></td>
+ <td width='1' style='background-color: rgba(33,74,148,1)'></td>
+ <td width='1' style='background-color: rgba(25,74,156,1)'></td>
+ <td width='1' style='background-color: rgba(16,74,165,1)'></td>
+ <td width='1' style='background-color: rgba(8,74,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,181,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,66,8,1)'></td>
+ <td width='1' style='background-color: rgba(173,66,16,1)'></td>
+ <td width='1' style='background-color: rgba(165,66,25,1)'></td>
+ <td width='1' style='background-color: rgba(156,66,33,1)'></td>
+ <td width='1' style='background-color: rgba(148,66,41,1)'></td>
+ <td width='1' style='background-color: rgba(140,66,49,1)'></td>
+ <td width='1' style='background-color: rgba(132,66,58,1)'></td>
+ <td width='1' style='background-color: rgba(123,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(115,66,74,1)'></td>
+ <td width='1' style='background-color: rgba(107,66,82,1)'></td>
+ <td width='1' style='background-color: rgba(99,66,90,1)'></td>
+ <td width='1' style='background-color: rgba(90,66,99,1)'></td>
+ <td width='1' style='background-color: rgba(82,66,107,1)'></td>
+ <td width='1' style='background-color: rgba(74,66,115,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,123,1)'></td>
+ <td width='1' style='background-color: rgba(58,66,132,1)'></td>
+ <td width='1' style='background-color: rgba(49,66,140,1)'></td>
+ <td width='1' style='background-color: rgba(41,66,148,1)'></td>
+ <td width='1' style='background-color: rgba(33,66,156,1)'></td>
+ <td width='1' style='background-color: rgba(25,66,165,1)'></td>
+ <td width='1' style='background-color: rgba(16,66,173,1)'></td>
+ <td width='1' style='background-color: rgba(8,66,181,1)'></td>
+ <td width='1' style='background-color: rgba(0,66,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,58,8,1)'></td>
+ <td width='1' style='background-color: rgba(181,58,16,1)'></td>
+ <td width='1' style='background-color: rgba(173,58,25,1)'></td>
+ <td width='1' style='background-color: rgba(165,58,33,1)'></td>
+ <td width='1' style='background-color: rgba(156,58,41,1)'></td>
+ <td width='1' style='background-color: rgba(148,58,49,1)'></td>
+ <td width='1' style='background-color: rgba(140,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(132,58,66,1)'></td>
+ <td width='1' style='background-color: rgba(123,58,74,1)'></td>
+ <td width='1' style='background-color: rgba(115,58,82,1)'></td>
+ <td width='1' style='background-color: rgba(107,58,90,1)'></td>
+ <td width='1' style='background-color: rgba(99,58,99,1)'></td>
+ <td width='1' style='background-color: rgba(90,58,107,1)'></td>
+ <td width='1' style='background-color: rgba(82,58,115,1)'></td>
+ <td width='1' style='background-color: rgba(74,58,123,1)'></td>
+ <td width='1' style='background-color: rgba(66,58,132,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,140,1)'></td>
+ <td width='1' style='background-color: rgba(49,58,148,1)'></td>
+ <td width='1' style='background-color: rgba(41,58,156,1)'></td>
+ <td width='1' style='background-color: rgba(33,58,165,1)'></td>
+ <td width='1' style='background-color: rgba(25,58,173,1)'></td>
+ <td width='1' style='background-color: rgba(16,58,181,1)'></td>
+ <td width='1' style='background-color: rgba(8,58,189,1)'></td>
+ <td width='1' style='background-color: rgba(0,58,197,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,49,8,1)'></td>
+ <td width='1' style='background-color: rgba(189,49,16,1)'></td>
+ <td width='1' style='background-color: rgba(181,49,25,1)'></td>
+ <td width='1' style='background-color: rgba(173,49,33,1)'></td>
+ <td width='1' style='background-color: rgba(165,49,41,1)'></td>
+ <td width='1' style='background-color: rgba(156,49,49,1)'></td>
+ <td width='1' style='background-color: rgba(148,49,58,1)'></td>
+ <td width='1' style='background-color: rgba(140,49,66,1)'></td>
+ <td width='1' style='background-color: rgba(132,49,74,1)'></td>
+ <td width='1' style='background-color: rgba(123,49,82,1)'></td>
+ <td width='1' style='background-color: rgba(115,49,90,1)'></td>
+ <td width='1' style='background-color: rgba(107,49,99,1)'></td>
+ <td width='1' style='background-color: rgba(99,49,107,1)'></td>
+ <td width='1' style='background-color: rgba(90,49,115,1)'></td>
+ <td width='1' style='background-color: rgba(82,49,123,1)'></td>
+ <td width='1' style='background-color: rgba(74,49,132,1)'></td>
+ <td width='1' style='background-color: rgba(66,49,140,1)'></td>
+ <td width='1' style='background-color: rgba(58,49,148,1)'></td>
+ <td width='1' style='background-color: rgba(49,49,156,1)'></td>
+ <td width='1' style='background-color: rgba(41,49,165,1)'></td>
+ <td width='1' style='background-color: rgba(33,49,173,1)'></td>
+ <td width='1' style='background-color: rgba(25,49,181,1)'></td>
+ <td width='1' style='background-color: rgba(16,49,189,1)'></td>
+ <td width='1' style='background-color: rgba(8,49,197,1)'></td>
+ <td width='1' style='background-color: rgba(0,49,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,41,8,1)'></td>
+ <td width='1' style='background-color: rgba(197,41,16,1)'></td>
+ <td width='1' style='background-color: rgba(189,41,25,1)'></td>
+ <td width='1' style='background-color: rgba(181,41,33,1)'></td>
+ <td width='1' style='background-color: rgba(173,41,41,1)'></td>
+ <td width='1' style='background-color: rgba(165,41,49,1)'></td>
+ <td width='1' style='background-color: rgba(156,41,58,1)'></td>
+ <td width='1' style='background-color: rgba(148,41,66,1)'></td>
+ <td width='1' style='background-color: rgba(140,41,74,1)'></td>
+ <td width='1' style='background-color: rgba(132,41,82,1)'></td>
+ <td width='1' style='background-color: rgba(123,41,90,1)'></td>
+ <td width='1' style='background-color: rgba(115,41,99,1)'></td>
+ <td width='1' style='background-color: rgba(107,41,107,1)'></td>
+ <td width='1' style='background-color: rgba(99,41,115,1)'></td>
+ <td width='1' style='background-color: rgba(90,41,123,1)'></td>
+ <td width='1' style='background-color: rgba(82,41,132,1)'></td>
+ <td width='1' style='background-color: rgba(74,41,140,1)'></td>
+ <td width='1' style='background-color: rgba(66,41,148,1)'></td>
+ <td width='1' style='background-color: rgba(58,41,156,1)'></td>
+ <td width='1' style='background-color: rgba(49,41,165,1)'></td>
+ <td width='1' style='background-color: rgba(41,41,173,1)'></td>
+ <td width='1' style='background-color: rgba(33,41,181,1)'></td>
+ <td width='1' style='background-color: rgba(25,41,189,1)'></td>
+ <td width='1' style='background-color: rgba(16,41,197,1)'></td>
+ <td width='1' style='background-color: rgba(8,41,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,41,214,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,33,8,1)'></td>
+ <td width='1' style='background-color: rgba(206,33,16,1)'></td>
+ <td width='1' style='background-color: rgba(197,33,25,1)'></td>
+ <td width='1' style='background-color: rgba(189,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(181,33,41,1)'></td>
+ <td width='1' style='background-color: rgba(173,33,49,1)'></td>
+ <td width='1' style='background-color: rgba(165,33,58,1)'></td>
+ <td width='1' style='background-color: rgba(156,33,66,1)'></td>
+ <td width='1' style='background-color: rgba(148,33,74,1)'></td>
+ <td width='1' style='background-color: rgba(140,33,82,1)'></td>
+ <td width='1' style='background-color: rgba(132,33,90,1)'></td>
+ <td width='1' style='background-color: rgba(123,33,99,1)'></td>
+ <td width='1' style='background-color: rgba(115,33,107,1)'></td>
+ <td width='1' style='background-color: rgba(107,33,115,1)'></td>
+ <td width='1' style='background-color: rgba(99,33,123,1)'></td>
+ <td width='1' style='background-color: rgba(90,33,132,1)'></td>
+ <td width='1' style='background-color: rgba(82,33,140,1)'></td>
+ <td width='1' style='background-color: rgba(74,33,148,1)'></td>
+ <td width='1' style='background-color: rgba(66,33,156,1)'></td>
+ <td width='1' style='background-color: rgba(58,33,165,1)'></td>
+ <td width='1' style='background-color: rgba(49,33,173,1)'></td>
+ <td width='1' style='background-color: rgba(41,33,181,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,189,1)'></td>
+ <td width='1' style='background-color: rgba(25,33,197,1)'></td>
+ <td width='1' style='background-color: rgba(16,33,206,1)'></td>
+ <td width='1' style='background-color: rgba(8,33,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,222,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,25,8,1)'></td>
+ <td width='1' style='background-color: rgba(214,25,16,1)'></td>
+ <td width='1' style='background-color: rgba(206,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(197,25,33,1)'></td>
+ <td width='1' style='background-color: rgba(189,25,41,1)'></td>
+ <td width='1' style='background-color: rgba(181,25,49,1)'></td>
+ <td width='1' style='background-color: rgba(173,25,58,1)'></td>
+ <td width='1' style='background-color: rgba(165,25,66,1)'></td>
+ <td width='1' style='background-color: rgba(156,25,74,1)'></td>
+ <td width='1' style='background-color: rgba(148,25,82,1)'></td>
+ <td width='1' style='background-color: rgba(140,25,90,1)'></td>
+ <td width='1' style='background-color: rgba(132,25,99,1)'></td>
+ <td width='1' style='background-color: rgba(123,25,107,1)'></td>
+ <td width='1' style='background-color: rgba(115,25,115,1)'></td>
+ <td width='1' style='background-color: rgba(107,25,123,1)'></td>
+ <td width='1' style='background-color: rgba(99,25,132,1)'></td>
+ <td width='1' style='background-color: rgba(90,25,140,1)'></td>
+ <td width='1' style='background-color: rgba(82,25,148,1)'></td>
+ <td width='1' style='background-color: rgba(74,25,156,1)'></td>
+ <td width='1' style='background-color: rgba(66,25,165,1)'></td>
+ <td width='1' style='background-color: rgba(58,25,173,1)'></td>
+ <td width='1' style='background-color: rgba(49,25,181,1)'></td>
+ <td width='1' style='background-color: rgba(41,25,189,1)'></td>
+ <td width='1' style='background-color: rgba(33,25,197,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,206,1)'></td>
+ <td width='1' style='background-color: rgba(16,25,214,1)'></td>
+ <td width='1' style='background-color: rgba(8,25,222,1)'></td>
+ <td width='1' style='background-color: rgba(0,25,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,16,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,16,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,16,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,16,8,1)'></td>
+ <td width='1' style='background-color: rgba(222,16,16,1)'></td>
+ <td width='1' style='background-color: rgba(214,16,25,1)'></td>
+ <td width='1' style='background-color: rgba(206,16,33,1)'></td>
+ <td width='1' style='background-color: rgba(197,16,41,1)'></td>
+ <td width='1' style='background-color: rgba(189,16,49,1)'></td>
+ <td width='1' style='background-color: rgba(181,16,58,1)'></td>
+ <td width='1' style='background-color: rgba(173,16,66,1)'></td>
+ <td width='1' style='background-color: rgba(165,16,74,1)'></td>
+ <td width='1' style='background-color: rgba(156,16,82,1)'></td>
+ <td width='1' style='background-color: rgba(148,16,90,1)'></td>
+ <td width='1' style='background-color: rgba(140,16,99,1)'></td>
+ <td width='1' style='background-color: rgba(132,16,107,1)'></td>
+ <td width='1' style='background-color: rgba(123,16,115,1)'></td>
+ <td width='1' style='background-color: rgba(115,16,123,1)'></td>
+ <td width='1' style='background-color: rgba(107,16,132,1)'></td>
+ <td width='1' style='background-color: rgba(99,16,140,1)'></td>
+ <td width='1' style='background-color: rgba(90,16,148,1)'></td>
+ <td width='1' style='background-color: rgba(82,16,156,1)'></td>
+ <td width='1' style='background-color: rgba(74,16,165,1)'></td>
+ <td width='1' style='background-color: rgba(66,16,173,1)'></td>
+ <td width='1' style='background-color: rgba(58,16,181,1)'></td>
+ <td width='1' style='background-color: rgba(49,16,189,1)'></td>
+ <td width='1' style='background-color: rgba(41,16,197,1)'></td>
+ <td width='1' style='background-color: rgba(33,16,206,1)'></td>
+ <td width='1' style='background-color: rgba(25,16,214,1)'></td>
+ <td width='1' style='background-color: rgba(16,16,222,1)'></td>
+ <td width='1' style='background-color: rgba(8,16,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,8,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,8,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(230,8,16,1)'></td>
+ <td width='1' style='background-color: rgba(222,8,25,1)'></td>
+ <td width='1' style='background-color: rgba(214,8,33,1)'></td>
+ <td width='1' style='background-color: rgba(206,8,41,1)'></td>
+ <td width='1' style='background-color: rgba(197,8,49,1)'></td>
+ <td width='1' style='background-color: rgba(189,8,58,1)'></td>
+ <td width='1' style='background-color: rgba(181,8,66,1)'></td>
+ <td width='1' style='background-color: rgba(173,8,74,1)'></td>
+ <td width='1' style='background-color: rgba(165,8,82,1)'></td>
+ <td width='1' style='background-color: rgba(156,8,90,1)'></td>
+ <td width='1' style='background-color: rgba(148,8,99,1)'></td>
+ <td width='1' style='background-color: rgba(140,8,107,1)'></td>
+ <td width='1' style='background-color: rgba(132,8,115,1)'></td>
+ <td width='1' style='background-color: rgba(123,8,123,1)'></td>
+ <td width='1' style='background-color: rgba(115,8,132,1)'></td>
+ <td width='1' style='background-color: rgba(107,8,140,1)'></td>
+ <td width='1' style='background-color: rgba(99,8,148,1)'></td>
+ <td width='1' style='background-color: rgba(90,8,156,1)'></td>
+ <td width='1' style='background-color: rgba(82,8,165,1)'></td>
+ <td width='1' style='background-color: rgba(74,8,173,1)'></td>
+ <td width='1' style='background-color: rgba(66,8,181,1)'></td>
+ <td width='1' style='background-color: rgba(58,8,189,1)'></td>
+ <td width='1' style='background-color: rgba(49,8,197,1)'></td>
+ <td width='1' style='background-color: rgba(41,8,206,1)'></td>
+ <td width='1' style='background-color: rgba(33,8,214,1)'></td>
+ <td width='1' style='background-color: rgba(25,8,222,1)'></td>
+ <td width='1' style='background-color: rgba(16,8,230,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,8,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,16,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,25,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,33,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,41,1)'></td>
+ <td width='1' style='background-color: rgba(206,0,49,1)'></td>
+ <td width='1' style='background-color: rgba(197,0,58,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,66,1)'></td>
+ <td width='1' style='background-color: rgba(181,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(173,0,82,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,90,1)'></td>
+ <td width='1' style='background-color: rgba(156,0,99,1)'></td>
+ <td width='1' style='background-color: rgba(148,0,107,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,115,1)'></td>
+ <td width='1' style='background-color: rgba(132,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,132,1)'></td>
+ <td width='1' style='background-color: rgba(115,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(107,0,148,1)'></td>
+ <td width='1' style='background-color: rgba(99,0,156,1)'></td>
+ <td width='1' style='background-color: rgba(90,0,165,1)'></td>
+ <td width='1' style='background-color: rgba(82,0,173,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,181,1)'></td>
+ <td width='1' style='background-color: rgba(66,0,189,1)'></td>
+ <td width='1' style='background-color: rgba(58,0,197,1)'></td>
+ <td width='1' style='background-color: rgba(49,0,206,1)'></td>
+ <td width='1' style='background-color: rgba(41,0,214,1)'></td>
+ <td width='1' style='background-color: rgba(33,0,222,1)'></td>
+ <td width='1' style='background-color: rgba(25,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(16,0,239,1)'></td>
+ <td width='1' style='background-color: rgba(8,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-zlib/z06n2c08.png b/image/test/reftest/pngsuite-zlib/z06n2c08.png
new file mode 100644
index 0000000000..b90ebc10f5
--- /dev/null
+++ b/image/test/reftest/pngsuite-zlib/z06n2c08.png
Binary files differ
diff --git a/image/test/reftest/pngsuite-zlib/z09n2c08.html b/image/test/reftest/pngsuite-zlib/z09n2c08.html
new file mode 100644
index 0000000000..c878a03ff6
--- /dev/null
+++ b/image/test/reftest/pngsuite-zlib/z09n2c08.html
@@ -0,0 +1,1094 @@
+<html>
+<head><link rel="stylesheet" href="../ImageDocument.css"></head>
+<body>
+<table cellpadding='0' cellspacing='0' width='32' height='32'>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(8,255,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,255,0,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(8,247,0,1)'></td>
+ <td width='1' style='background-color: rgba(0,247,8,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,239,0,1)'></td>
+ <td width='1' style='background-color: rgba(8,239,8,1)'></td>
+ <td width='1' style='background-color: rgba(0,239,16,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,230,0,1)'></td>
+ <td width='1' style='background-color: rgba(16,230,8,1)'></td>
+ <td width='1' style='background-color: rgba(8,230,16,1)'></td>
+ <td width='1' style='background-color: rgba(0,230,25,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,222,0,1)'></td>
+ <td width='1' style='background-color: rgba(25,222,8,1)'></td>
+ <td width='1' style='background-color: rgba(16,222,16,1)'></td>
+ <td width='1' style='background-color: rgba(8,222,25,1)'></td>
+ <td width='1' style='background-color: rgba(0,222,33,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,214,0,1)'></td>
+ <td width='1' style='background-color: rgba(33,214,8,1)'></td>
+ <td width='1' style='background-color: rgba(25,214,16,1)'></td>
+ <td width='1' style='background-color: rgba(16,214,25,1)'></td>
+ <td width='1' style='background-color: rgba(8,214,33,1)'></td>
+ <td width='1' style='background-color: rgba(0,214,41,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,206,0,1)'></td>
+ <td width='1' style='background-color: rgba(41,206,8,1)'></td>
+ <td width='1' style='background-color: rgba(33,206,16,1)'></td>
+ <td width='1' style='background-color: rgba(25,206,25,1)'></td>
+ <td width='1' style='background-color: rgba(16,206,33,1)'></td>
+ <td width='1' style='background-color: rgba(8,206,41,1)'></td>
+ <td width='1' style='background-color: rgba(0,206,49,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,197,0,1)'></td>
+ <td width='1' style='background-color: rgba(49,197,8,1)'></td>
+ <td width='1' style='background-color: rgba(41,197,16,1)'></td>
+ <td width='1' style='background-color: rgba(33,197,25,1)'></td>
+ <td width='1' style='background-color: rgba(25,197,33,1)'></td>
+ <td width='1' style='background-color: rgba(16,197,41,1)'></td>
+ <td width='1' style='background-color: rgba(8,197,49,1)'></td>
+ <td width='1' style='background-color: rgba(0,197,58,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,189,0,1)'></td>
+ <td width='1' style='background-color: rgba(58,189,8,1)'></td>
+ <td width='1' style='background-color: rgba(49,189,16,1)'></td>
+ <td width='1' style='background-color: rgba(41,189,25,1)'></td>
+ <td width='1' style='background-color: rgba(33,189,33,1)'></td>
+ <td width='1' style='background-color: rgba(25,189,41,1)'></td>
+ <td width='1' style='background-color: rgba(16,189,49,1)'></td>
+ <td width='1' style='background-color: rgba(8,189,58,1)'></td>
+ <td width='1' style='background-color: rgba(0,189,66,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,181,0,1)'></td>
+ <td width='1' style='background-color: rgba(66,181,8,1)'></td>
+ <td width='1' style='background-color: rgba(58,181,16,1)'></td>
+ <td width='1' style='background-color: rgba(49,181,25,1)'></td>
+ <td width='1' style='background-color: rgba(41,181,33,1)'></td>
+ <td width='1' style='background-color: rgba(33,181,41,1)'></td>
+ <td width='1' style='background-color: rgba(25,181,49,1)'></td>
+ <td width='1' style='background-color: rgba(16,181,58,1)'></td>
+ <td width='1' style='background-color: rgba(8,181,66,1)'></td>
+ <td width='1' style='background-color: rgba(0,181,74,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,173,0,1)'></td>
+ <td width='1' style='background-color: rgba(74,173,8,1)'></td>
+ <td width='1' style='background-color: rgba(66,173,16,1)'></td>
+ <td width='1' style='background-color: rgba(58,173,25,1)'></td>
+ <td width='1' style='background-color: rgba(49,173,33,1)'></td>
+ <td width='1' style='background-color: rgba(41,173,41,1)'></td>
+ <td width='1' style='background-color: rgba(33,173,49,1)'></td>
+ <td width='1' style='background-color: rgba(25,173,58,1)'></td>
+ <td width='1' style='background-color: rgba(16,173,66,1)'></td>
+ <td width='1' style='background-color: rgba(8,173,74,1)'></td>
+ <td width='1' style='background-color: rgba(0,173,82,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,165,0,1)'></td>
+ <td width='1' style='background-color: rgba(82,165,8,1)'></td>
+ <td width='1' style='background-color: rgba(74,165,16,1)'></td>
+ <td width='1' style='background-color: rgba(66,165,25,1)'></td>
+ <td width='1' style='background-color: rgba(58,165,33,1)'></td>
+ <td width='1' style='background-color: rgba(49,165,41,1)'></td>
+ <td width='1' style='background-color: rgba(41,165,49,1)'></td>
+ <td width='1' style='background-color: rgba(33,165,58,1)'></td>
+ <td width='1' style='background-color: rgba(25,165,66,1)'></td>
+ <td width='1' style='background-color: rgba(16,165,74,1)'></td>
+ <td width='1' style='background-color: rgba(8,165,82,1)'></td>
+ <td width='1' style='background-color: rgba(0,165,90,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,156,0,1)'></td>
+ <td width='1' style='background-color: rgba(90,156,8,1)'></td>
+ <td width='1' style='background-color: rgba(82,156,16,1)'></td>
+ <td width='1' style='background-color: rgba(74,156,25,1)'></td>
+ <td width='1' style='background-color: rgba(66,156,33,1)'></td>
+ <td width='1' style='background-color: rgba(58,156,41,1)'></td>
+ <td width='1' style='background-color: rgba(49,156,49,1)'></td>
+ <td width='1' style='background-color: rgba(41,156,58,1)'></td>
+ <td width='1' style='background-color: rgba(33,156,66,1)'></td>
+ <td width='1' style='background-color: rgba(25,156,74,1)'></td>
+ <td width='1' style='background-color: rgba(16,156,82,1)'></td>
+ <td width='1' style='background-color: rgba(8,156,90,1)'></td>
+ <td width='1' style='background-color: rgba(0,156,99,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,148,0,1)'></td>
+ <td width='1' style='background-color: rgba(99,148,8,1)'></td>
+ <td width='1' style='background-color: rgba(90,148,16,1)'></td>
+ <td width='1' style='background-color: rgba(82,148,25,1)'></td>
+ <td width='1' style='background-color: rgba(74,148,33,1)'></td>
+ <td width='1' style='background-color: rgba(66,148,41,1)'></td>
+ <td width='1' style='background-color: rgba(58,148,49,1)'></td>
+ <td width='1' style='background-color: rgba(49,148,58,1)'></td>
+ <td width='1' style='background-color: rgba(41,148,66,1)'></td>
+ <td width='1' style='background-color: rgba(33,148,74,1)'></td>
+ <td width='1' style='background-color: rgba(25,148,82,1)'></td>
+ <td width='1' style='background-color: rgba(16,148,90,1)'></td>
+ <td width='1' style='background-color: rgba(8,148,99,1)'></td>
+ <td width='1' style='background-color: rgba(0,148,107,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,140,0,1)'></td>
+ <td width='1' style='background-color: rgba(107,140,8,1)'></td>
+ <td width='1' style='background-color: rgba(99,140,16,1)'></td>
+ <td width='1' style='background-color: rgba(90,140,25,1)'></td>
+ <td width='1' style='background-color: rgba(82,140,33,1)'></td>
+ <td width='1' style='background-color: rgba(74,140,41,1)'></td>
+ <td width='1' style='background-color: rgba(66,140,49,1)'></td>
+ <td width='1' style='background-color: rgba(58,140,58,1)'></td>
+ <td width='1' style='background-color: rgba(49,140,66,1)'></td>
+ <td width='1' style='background-color: rgba(41,140,74,1)'></td>
+ <td width='1' style='background-color: rgba(33,140,82,1)'></td>
+ <td width='1' style='background-color: rgba(25,140,90,1)'></td>
+ <td width='1' style='background-color: rgba(16,140,99,1)'></td>
+ <td width='1' style='background-color: rgba(8,140,107,1)'></td>
+ <td width='1' style='background-color: rgba(0,140,115,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,132,0,1)'></td>
+ <td width='1' style='background-color: rgba(115,132,8,1)'></td>
+ <td width='1' style='background-color: rgba(107,132,16,1)'></td>
+ <td width='1' style='background-color: rgba(99,132,25,1)'></td>
+ <td width='1' style='background-color: rgba(90,132,33,1)'></td>
+ <td width='1' style='background-color: rgba(82,132,41,1)'></td>
+ <td width='1' style='background-color: rgba(74,132,49,1)'></td>
+ <td width='1' style='background-color: rgba(66,132,58,1)'></td>
+ <td width='1' style='background-color: rgba(58,132,66,1)'></td>
+ <td width='1' style='background-color: rgba(49,132,74,1)'></td>
+ <td width='1' style='background-color: rgba(41,132,82,1)'></td>
+ <td width='1' style='background-color: rgba(33,132,90,1)'></td>
+ <td width='1' style='background-color: rgba(25,132,99,1)'></td>
+ <td width='1' style='background-color: rgba(16,132,107,1)'></td>
+ <td width='1' style='background-color: rgba(8,132,115,1)'></td>
+ <td width='1' style='background-color: rgba(0,132,123,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,123,0,1)'></td>
+ <td width='1' style='background-color: rgba(123,123,8,1)'></td>
+ <td width='1' style='background-color: rgba(115,123,16,1)'></td>
+ <td width='1' style='background-color: rgba(107,123,25,1)'></td>
+ <td width='1' style='background-color: rgba(99,123,33,1)'></td>
+ <td width='1' style='background-color: rgba(90,123,41,1)'></td>
+ <td width='1' style='background-color: rgba(82,123,49,1)'></td>
+ <td width='1' style='background-color: rgba(74,123,58,1)'></td>
+ <td width='1' style='background-color: rgba(66,123,66,1)'></td>
+ <td width='1' style='background-color: rgba(58,123,74,1)'></td>
+ <td width='1' style='background-color: rgba(49,123,82,1)'></td>
+ <td width='1' style='background-color: rgba(41,123,90,1)'></td>
+ <td width='1' style='background-color: rgba(33,123,99,1)'></td>
+ <td width='1' style='background-color: rgba(25,123,107,1)'></td>
+ <td width='1' style='background-color: rgba(16,123,115,1)'></td>
+ <td width='1' style='background-color: rgba(8,123,123,1)'></td>
+ <td width='1' style='background-color: rgba(0,123,132,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,115,0,1)'></td>
+ <td width='1' style='background-color: rgba(132,115,8,1)'></td>
+ <td width='1' style='background-color: rgba(123,115,16,1)'></td>
+ <td width='1' style='background-color: rgba(115,115,25,1)'></td>
+ <td width='1' style='background-color: rgba(107,115,33,1)'></td>
+ <td width='1' style='background-color: rgba(99,115,41,1)'></td>
+ <td width='1' style='background-color: rgba(90,115,49,1)'></td>
+ <td width='1' style='background-color: rgba(82,115,58,1)'></td>
+ <td width='1' style='background-color: rgba(74,115,66,1)'></td>
+ <td width='1' style='background-color: rgba(66,115,74,1)'></td>
+ <td width='1' style='background-color: rgba(58,115,82,1)'></td>
+ <td width='1' style='background-color: rgba(49,115,90,1)'></td>
+ <td width='1' style='background-color: rgba(41,115,99,1)'></td>
+ <td width='1' style='background-color: rgba(33,115,107,1)'></td>
+ <td width='1' style='background-color: rgba(25,115,115,1)'></td>
+ <td width='1' style='background-color: rgba(16,115,123,1)'></td>
+ <td width='1' style='background-color: rgba(8,115,132,1)'></td>
+ <td width='1' style='background-color: rgba(0,115,140,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,107,0,1)'></td>
+ <td width='1' style='background-color: rgba(140,107,8,1)'></td>
+ <td width='1' style='background-color: rgba(132,107,16,1)'></td>
+ <td width='1' style='background-color: rgba(123,107,25,1)'></td>
+ <td width='1' style='background-color: rgba(115,107,33,1)'></td>
+ <td width='1' style='background-color: rgba(107,107,41,1)'></td>
+ <td width='1' style='background-color: rgba(99,107,49,1)'></td>
+ <td width='1' style='background-color: rgba(90,107,58,1)'></td>
+ <td width='1' style='background-color: rgba(82,107,66,1)'></td>
+ <td width='1' style='background-color: rgba(74,107,74,1)'></td>
+ <td width='1' style='background-color: rgba(66,107,82,1)'></td>
+ <td width='1' style='background-color: rgba(58,107,90,1)'></td>
+ <td width='1' style='background-color: rgba(49,107,99,1)'></td>
+ <td width='1' style='background-color: rgba(41,107,107,1)'></td>
+ <td width='1' style='background-color: rgba(33,107,115,1)'></td>
+ <td width='1' style='background-color: rgba(25,107,123,1)'></td>
+ <td width='1' style='background-color: rgba(16,107,132,1)'></td>
+ <td width='1' style='background-color: rgba(8,107,140,1)'></td>
+ <td width='1' style='background-color: rgba(0,107,148,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,99,0,1)'></td>
+ <td width='1' style='background-color: rgba(148,99,8,1)'></td>
+ <td width='1' style='background-color: rgba(140,99,16,1)'></td>
+ <td width='1' style='background-color: rgba(132,99,25,1)'></td>
+ <td width='1' style='background-color: rgba(123,99,33,1)'></td>
+ <td width='1' style='background-color: rgba(115,99,41,1)'></td>
+ <td width='1' style='background-color: rgba(107,99,49,1)'></td>
+ <td width='1' style='background-color: rgba(99,99,58,1)'></td>
+ <td width='1' style='background-color: rgba(90,99,66,1)'></td>
+ <td width='1' style='background-color: rgba(82,99,74,1)'></td>
+ <td width='1' style='background-color: rgba(74,99,82,1)'></td>
+ <td width='1' style='background-color: rgba(66,99,90,1)'></td>
+ <td width='1' style='background-color: rgba(58,99,99,1)'></td>
+ <td width='1' style='background-color: rgba(49,99,107,1)'></td>
+ <td width='1' style='background-color: rgba(41,99,115,1)'></td>
+ <td width='1' style='background-color: rgba(33,99,123,1)'></td>
+ <td width='1' style='background-color: rgba(25,99,132,1)'></td>
+ <td width='1' style='background-color: rgba(16,99,140,1)'></td>
+ <td width='1' style='background-color: rgba(8,99,148,1)'></td>
+ <td width='1' style='background-color: rgba(0,99,156,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,90,0,1)'></td>
+ <td width='1' style='background-color: rgba(156,90,8,1)'></td>
+ <td width='1' style='background-color: rgba(148,90,16,1)'></td>
+ <td width='1' style='background-color: rgba(140,90,25,1)'></td>
+ <td width='1' style='background-color: rgba(132,90,33,1)'></td>
+ <td width='1' style='background-color: rgba(123,90,41,1)'></td>
+ <td width='1' style='background-color: rgba(115,90,49,1)'></td>
+ <td width='1' style='background-color: rgba(107,90,58,1)'></td>
+ <td width='1' style='background-color: rgba(99,90,66,1)'></td>
+ <td width='1' style='background-color: rgba(90,90,74,1)'></td>
+ <td width='1' style='background-color: rgba(82,90,82,1)'></td>
+ <td width='1' style='background-color: rgba(74,90,90,1)'></td>
+ <td width='1' style='background-color: rgba(66,90,99,1)'></td>
+ <td width='1' style='background-color: rgba(58,90,107,1)'></td>
+ <td width='1' style='background-color: rgba(49,90,115,1)'></td>
+ <td width='1' style='background-color: rgba(41,90,123,1)'></td>
+ <td width='1' style='background-color: rgba(33,90,132,1)'></td>
+ <td width='1' style='background-color: rgba(25,90,140,1)'></td>
+ <td width='1' style='background-color: rgba(16,90,148,1)'></td>
+ <td width='1' style='background-color: rgba(8,90,156,1)'></td>
+ <td width='1' style='background-color: rgba(0,90,165,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,82,0,1)'></td>
+ <td width='1' style='background-color: rgba(165,82,8,1)'></td>
+ <td width='1' style='background-color: rgba(156,82,16,1)'></td>
+ <td width='1' style='background-color: rgba(148,82,25,1)'></td>
+ <td width='1' style='background-color: rgba(140,82,33,1)'></td>
+ <td width='1' style='background-color: rgba(132,82,41,1)'></td>
+ <td width='1' style='background-color: rgba(123,82,49,1)'></td>
+ <td width='1' style='background-color: rgba(115,82,58,1)'></td>
+ <td width='1' style='background-color: rgba(107,82,66,1)'></td>
+ <td width='1' style='background-color: rgba(99,82,74,1)'></td>
+ <td width='1' style='background-color: rgba(90,82,82,1)'></td>
+ <td width='1' style='background-color: rgba(82,82,90,1)'></td>
+ <td width='1' style='background-color: rgba(74,82,99,1)'></td>
+ <td width='1' style='background-color: rgba(66,82,107,1)'></td>
+ <td width='1' style='background-color: rgba(58,82,115,1)'></td>
+ <td width='1' style='background-color: rgba(49,82,123,1)'></td>
+ <td width='1' style='background-color: rgba(41,82,132,1)'></td>
+ <td width='1' style='background-color: rgba(33,82,140,1)'></td>
+ <td width='1' style='background-color: rgba(25,82,148,1)'></td>
+ <td width='1' style='background-color: rgba(16,82,156,1)'></td>
+ <td width='1' style='background-color: rgba(8,82,165,1)'></td>
+ <td width='1' style='background-color: rgba(0,82,173,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,74,0,1)'></td>
+ <td width='1' style='background-color: rgba(173,74,8,1)'></td>
+ <td width='1' style='background-color: rgba(165,74,16,1)'></td>
+ <td width='1' style='background-color: rgba(156,74,25,1)'></td>
+ <td width='1' style='background-color: rgba(148,74,33,1)'></td>
+ <td width='1' style='background-color: rgba(140,74,41,1)'></td>
+ <td width='1' style='background-color: rgba(132,74,49,1)'></td>
+ <td width='1' style='background-color: rgba(123,74,58,1)'></td>
+ <td width='1' style='background-color: rgba(115,74,66,1)'></td>
+ <td width='1' style='background-color: rgba(107,74,74,1)'></td>
+ <td width='1' style='background-color: rgba(99,74,82,1)'></td>
+ <td width='1' style='background-color: rgba(90,74,90,1)'></td>
+ <td width='1' style='background-color: rgba(82,74,99,1)'></td>
+ <td width='1' style='background-color: rgba(74,74,107,1)'></td>
+ <td width='1' style='background-color: rgba(66,74,115,1)'></td>
+ <td width='1' style='background-color: rgba(58,74,123,1)'></td>
+ <td width='1' style='background-color: rgba(49,74,132,1)'></td>
+ <td width='1' style='background-color: rgba(41,74,140,1)'></td>
+ <td width='1' style='background-color: rgba(33,74,148,1)'></td>
+ <td width='1' style='background-color: rgba(25,74,156,1)'></td>
+ <td width='1' style='background-color: rgba(16,74,165,1)'></td>
+ <td width='1' style='background-color: rgba(8,74,173,1)'></td>
+ <td width='1' style='background-color: rgba(0,74,181,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,66,0,1)'></td>
+ <td width='1' style='background-color: rgba(181,66,8,1)'></td>
+ <td width='1' style='background-color: rgba(173,66,16,1)'></td>
+ <td width='1' style='background-color: rgba(165,66,25,1)'></td>
+ <td width='1' style='background-color: rgba(156,66,33,1)'></td>
+ <td width='1' style='background-color: rgba(148,66,41,1)'></td>
+ <td width='1' style='background-color: rgba(140,66,49,1)'></td>
+ <td width='1' style='background-color: rgba(132,66,58,1)'></td>
+ <td width='1' style='background-color: rgba(123,66,66,1)'></td>
+ <td width='1' style='background-color: rgba(115,66,74,1)'></td>
+ <td width='1' style='background-color: rgba(107,66,82,1)'></td>
+ <td width='1' style='background-color: rgba(99,66,90,1)'></td>
+ <td width='1' style='background-color: rgba(90,66,99,1)'></td>
+ <td width='1' style='background-color: rgba(82,66,107,1)'></td>
+ <td width='1' style='background-color: rgba(74,66,115,1)'></td>
+ <td width='1' style='background-color: rgba(66,66,123,1)'></td>
+ <td width='1' style='background-color: rgba(58,66,132,1)'></td>
+ <td width='1' style='background-color: rgba(49,66,140,1)'></td>
+ <td width='1' style='background-color: rgba(41,66,148,1)'></td>
+ <td width='1' style='background-color: rgba(33,66,156,1)'></td>
+ <td width='1' style='background-color: rgba(25,66,165,1)'></td>
+ <td width='1' style='background-color: rgba(16,66,173,1)'></td>
+ <td width='1' style='background-color: rgba(8,66,181,1)'></td>
+ <td width='1' style='background-color: rgba(0,66,189,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,58,0,1)'></td>
+ <td width='1' style='background-color: rgba(189,58,8,1)'></td>
+ <td width='1' style='background-color: rgba(181,58,16,1)'></td>
+ <td width='1' style='background-color: rgba(173,58,25,1)'></td>
+ <td width='1' style='background-color: rgba(165,58,33,1)'></td>
+ <td width='1' style='background-color: rgba(156,58,41,1)'></td>
+ <td width='1' style='background-color: rgba(148,58,49,1)'></td>
+ <td width='1' style='background-color: rgba(140,58,58,1)'></td>
+ <td width='1' style='background-color: rgba(132,58,66,1)'></td>
+ <td width='1' style='background-color: rgba(123,58,74,1)'></td>
+ <td width='1' style='background-color: rgba(115,58,82,1)'></td>
+ <td width='1' style='background-color: rgba(107,58,90,1)'></td>
+ <td width='1' style='background-color: rgba(99,58,99,1)'></td>
+ <td width='1' style='background-color: rgba(90,58,107,1)'></td>
+ <td width='1' style='background-color: rgba(82,58,115,1)'></td>
+ <td width='1' style='background-color: rgba(74,58,123,1)'></td>
+ <td width='1' style='background-color: rgba(66,58,132,1)'></td>
+ <td width='1' style='background-color: rgba(58,58,140,1)'></td>
+ <td width='1' style='background-color: rgba(49,58,148,1)'></td>
+ <td width='1' style='background-color: rgba(41,58,156,1)'></td>
+ <td width='1' style='background-color: rgba(33,58,165,1)'></td>
+ <td width='1' style='background-color: rgba(25,58,173,1)'></td>
+ <td width='1' style='background-color: rgba(16,58,181,1)'></td>
+ <td width='1' style='background-color: rgba(8,58,189,1)'></td>
+ <td width='1' style='background-color: rgba(0,58,197,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,49,0,1)'></td>
+ <td width='1' style='background-color: rgba(197,49,8,1)'></td>
+ <td width='1' style='background-color: rgba(189,49,16,1)'></td>
+ <td width='1' style='background-color: rgba(181,49,25,1)'></td>
+ <td width='1' style='background-color: rgba(173,49,33,1)'></td>
+ <td width='1' style='background-color: rgba(165,49,41,1)'></td>
+ <td width='1' style='background-color: rgba(156,49,49,1)'></td>
+ <td width='1' style='background-color: rgba(148,49,58,1)'></td>
+ <td width='1' style='background-color: rgba(140,49,66,1)'></td>
+ <td width='1' style='background-color: rgba(132,49,74,1)'></td>
+ <td width='1' style='background-color: rgba(123,49,82,1)'></td>
+ <td width='1' style='background-color: rgba(115,49,90,1)'></td>
+ <td width='1' style='background-color: rgba(107,49,99,1)'></td>
+ <td width='1' style='background-color: rgba(99,49,107,1)'></td>
+ <td width='1' style='background-color: rgba(90,49,115,1)'></td>
+ <td width='1' style='background-color: rgba(82,49,123,1)'></td>
+ <td width='1' style='background-color: rgba(74,49,132,1)'></td>
+ <td width='1' style='background-color: rgba(66,49,140,1)'></td>
+ <td width='1' style='background-color: rgba(58,49,148,1)'></td>
+ <td width='1' style='background-color: rgba(49,49,156,1)'></td>
+ <td width='1' style='background-color: rgba(41,49,165,1)'></td>
+ <td width='1' style='background-color: rgba(33,49,173,1)'></td>
+ <td width='1' style='background-color: rgba(25,49,181,1)'></td>
+ <td width='1' style='background-color: rgba(16,49,189,1)'></td>
+ <td width='1' style='background-color: rgba(8,49,197,1)'></td>
+ <td width='1' style='background-color: rgba(0,49,206,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,41,0,1)'></td>
+ <td width='1' style='background-color: rgba(206,41,8,1)'></td>
+ <td width='1' style='background-color: rgba(197,41,16,1)'></td>
+ <td width='1' style='background-color: rgba(189,41,25,1)'></td>
+ <td width='1' style='background-color: rgba(181,41,33,1)'></td>
+ <td width='1' style='background-color: rgba(173,41,41,1)'></td>
+ <td width='1' style='background-color: rgba(165,41,49,1)'></td>
+ <td width='1' style='background-color: rgba(156,41,58,1)'></td>
+ <td width='1' style='background-color: rgba(148,41,66,1)'></td>
+ <td width='1' style='background-color: rgba(140,41,74,1)'></td>
+ <td width='1' style='background-color: rgba(132,41,82,1)'></td>
+ <td width='1' style='background-color: rgba(123,41,90,1)'></td>
+ <td width='1' style='background-color: rgba(115,41,99,1)'></td>
+ <td width='1' style='background-color: rgba(107,41,107,1)'></td>
+ <td width='1' style='background-color: rgba(99,41,115,1)'></td>
+ <td width='1' style='background-color: rgba(90,41,123,1)'></td>
+ <td width='1' style='background-color: rgba(82,41,132,1)'></td>
+ <td width='1' style='background-color: rgba(74,41,140,1)'></td>
+ <td width='1' style='background-color: rgba(66,41,148,1)'></td>
+ <td width='1' style='background-color: rgba(58,41,156,1)'></td>
+ <td width='1' style='background-color: rgba(49,41,165,1)'></td>
+ <td width='1' style='background-color: rgba(41,41,173,1)'></td>
+ <td width='1' style='background-color: rgba(33,41,181,1)'></td>
+ <td width='1' style='background-color: rgba(25,41,189,1)'></td>
+ <td width='1' style='background-color: rgba(16,41,197,1)'></td>
+ <td width='1' style='background-color: rgba(8,41,206,1)'></td>
+ <td width='1' style='background-color: rgba(0,41,214,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,33,0,1)'></td>
+ <td width='1' style='background-color: rgba(214,33,8,1)'></td>
+ <td width='1' style='background-color: rgba(206,33,16,1)'></td>
+ <td width='1' style='background-color: rgba(197,33,25,1)'></td>
+ <td width='1' style='background-color: rgba(189,33,33,1)'></td>
+ <td width='1' style='background-color: rgba(181,33,41,1)'></td>
+ <td width='1' style='background-color: rgba(173,33,49,1)'></td>
+ <td width='1' style='background-color: rgba(165,33,58,1)'></td>
+ <td width='1' style='background-color: rgba(156,33,66,1)'></td>
+ <td width='1' style='background-color: rgba(148,33,74,1)'></td>
+ <td width='1' style='background-color: rgba(140,33,82,1)'></td>
+ <td width='1' style='background-color: rgba(132,33,90,1)'></td>
+ <td width='1' style='background-color: rgba(123,33,99,1)'></td>
+ <td width='1' style='background-color: rgba(115,33,107,1)'></td>
+ <td width='1' style='background-color: rgba(107,33,115,1)'></td>
+ <td width='1' style='background-color: rgba(99,33,123,1)'></td>
+ <td width='1' style='background-color: rgba(90,33,132,1)'></td>
+ <td width='1' style='background-color: rgba(82,33,140,1)'></td>
+ <td width='1' style='background-color: rgba(74,33,148,1)'></td>
+ <td width='1' style='background-color: rgba(66,33,156,1)'></td>
+ <td width='1' style='background-color: rgba(58,33,165,1)'></td>
+ <td width='1' style='background-color: rgba(49,33,173,1)'></td>
+ <td width='1' style='background-color: rgba(41,33,181,1)'></td>
+ <td width='1' style='background-color: rgba(33,33,189,1)'></td>
+ <td width='1' style='background-color: rgba(25,33,197,1)'></td>
+ <td width='1' style='background-color: rgba(16,33,206,1)'></td>
+ <td width='1' style='background-color: rgba(8,33,214,1)'></td>
+ <td width='1' style='background-color: rgba(0,33,222,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,25,0,1)'></td>
+ <td width='1' style='background-color: rgba(222,25,8,1)'></td>
+ <td width='1' style='background-color: rgba(214,25,16,1)'></td>
+ <td width='1' style='background-color: rgba(206,25,25,1)'></td>
+ <td width='1' style='background-color: rgba(197,25,33,1)'></td>
+ <td width='1' style='background-color: rgba(189,25,41,1)'></td>
+ <td width='1' style='background-color: rgba(181,25,49,1)'></td>
+ <td width='1' style='background-color: rgba(173,25,58,1)'></td>
+ <td width='1' style='background-color: rgba(165,25,66,1)'></td>
+ <td width='1' style='background-color: rgba(156,25,74,1)'></td>
+ <td width='1' style='background-color: rgba(148,25,82,1)'></td>
+ <td width='1' style='background-color: rgba(140,25,90,1)'></td>
+ <td width='1' style='background-color: rgba(132,25,99,1)'></td>
+ <td width='1' style='background-color: rgba(123,25,107,1)'></td>
+ <td width='1' style='background-color: rgba(115,25,115,1)'></td>
+ <td width='1' style='background-color: rgba(107,25,123,1)'></td>
+ <td width='1' style='background-color: rgba(99,25,132,1)'></td>
+ <td width='1' style='background-color: rgba(90,25,140,1)'></td>
+ <td width='1' style='background-color: rgba(82,25,148,1)'></td>
+ <td width='1' style='background-color: rgba(74,25,156,1)'></td>
+ <td width='1' style='background-color: rgba(66,25,165,1)'></td>
+ <td width='1' style='background-color: rgba(58,25,173,1)'></td>
+ <td width='1' style='background-color: rgba(49,25,181,1)'></td>
+ <td width='1' style='background-color: rgba(41,25,189,1)'></td>
+ <td width='1' style='background-color: rgba(33,25,197,1)'></td>
+ <td width='1' style='background-color: rgba(25,25,206,1)'></td>
+ <td width='1' style='background-color: rgba(16,25,214,1)'></td>
+ <td width='1' style='background-color: rgba(8,25,222,1)'></td>
+ <td width='1' style='background-color: rgba(0,25,230,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,16,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,16,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,16,0,1)'></td>
+ <td width='1' style='background-color: rgba(230,16,8,1)'></td>
+ <td width='1' style='background-color: rgba(222,16,16,1)'></td>
+ <td width='1' style='background-color: rgba(214,16,25,1)'></td>
+ <td width='1' style='background-color: rgba(206,16,33,1)'></td>
+ <td width='1' style='background-color: rgba(197,16,41,1)'></td>
+ <td width='1' style='background-color: rgba(189,16,49,1)'></td>
+ <td width='1' style='background-color: rgba(181,16,58,1)'></td>
+ <td width='1' style='background-color: rgba(173,16,66,1)'></td>
+ <td width='1' style='background-color: rgba(165,16,74,1)'></td>
+ <td width='1' style='background-color: rgba(156,16,82,1)'></td>
+ <td width='1' style='background-color: rgba(148,16,90,1)'></td>
+ <td width='1' style='background-color: rgba(140,16,99,1)'></td>
+ <td width='1' style='background-color: rgba(132,16,107,1)'></td>
+ <td width='1' style='background-color: rgba(123,16,115,1)'></td>
+ <td width='1' style='background-color: rgba(115,16,123,1)'></td>
+ <td width='1' style='background-color: rgba(107,16,132,1)'></td>
+ <td width='1' style='background-color: rgba(99,16,140,1)'></td>
+ <td width='1' style='background-color: rgba(90,16,148,1)'></td>
+ <td width='1' style='background-color: rgba(82,16,156,1)'></td>
+ <td width='1' style='background-color: rgba(74,16,165,1)'></td>
+ <td width='1' style='background-color: rgba(66,16,173,1)'></td>
+ <td width='1' style='background-color: rgba(58,16,181,1)'></td>
+ <td width='1' style='background-color: rgba(49,16,189,1)'></td>
+ <td width='1' style='background-color: rgba(41,16,197,1)'></td>
+ <td width='1' style='background-color: rgba(33,16,206,1)'></td>
+ <td width='1' style='background-color: rgba(25,16,214,1)'></td>
+ <td width='1' style='background-color: rgba(16,16,222,1)'></td>
+ <td width='1' style='background-color: rgba(8,16,230,1)'></td>
+ <td width='1' style='background-color: rgba(0,16,239,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,8,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,8,0,1)'></td>
+ <td width='1' style='background-color: rgba(239,8,8,1)'></td>
+ <td width='1' style='background-color: rgba(230,8,16,1)'></td>
+ <td width='1' style='background-color: rgba(222,8,25,1)'></td>
+ <td width='1' style='background-color: rgba(214,8,33,1)'></td>
+ <td width='1' style='background-color: rgba(206,8,41,1)'></td>
+ <td width='1' style='background-color: rgba(197,8,49,1)'></td>
+ <td width='1' style='background-color: rgba(189,8,58,1)'></td>
+ <td width='1' style='background-color: rgba(181,8,66,1)'></td>
+ <td width='1' style='background-color: rgba(173,8,74,1)'></td>
+ <td width='1' style='background-color: rgba(165,8,82,1)'></td>
+ <td width='1' style='background-color: rgba(156,8,90,1)'></td>
+ <td width='1' style='background-color: rgba(148,8,99,1)'></td>
+ <td width='1' style='background-color: rgba(140,8,107,1)'></td>
+ <td width='1' style='background-color: rgba(132,8,115,1)'></td>
+ <td width='1' style='background-color: rgba(123,8,123,1)'></td>
+ <td width='1' style='background-color: rgba(115,8,132,1)'></td>
+ <td width='1' style='background-color: rgba(107,8,140,1)'></td>
+ <td width='1' style='background-color: rgba(99,8,148,1)'></td>
+ <td width='1' style='background-color: rgba(90,8,156,1)'></td>
+ <td width='1' style='background-color: rgba(82,8,165,1)'></td>
+ <td width='1' style='background-color: rgba(74,8,173,1)'></td>
+ <td width='1' style='background-color: rgba(66,8,181,1)'></td>
+ <td width='1' style='background-color: rgba(58,8,189,1)'></td>
+ <td width='1' style='background-color: rgba(49,8,197,1)'></td>
+ <td width='1' style='background-color: rgba(41,8,206,1)'></td>
+ <td width='1' style='background-color: rgba(33,8,214,1)'></td>
+ <td width='1' style='background-color: rgba(25,8,222,1)'></td>
+ <td width='1' style='background-color: rgba(16,8,230,1)'></td>
+ <td width='1' style='background-color: rgba(8,8,239,1)'></td>
+ <td width='1' style='background-color: rgba(0,8,247,1)'></td>
+</tr>
+<tr height='1'>
+ <td width='1' style='background-color: rgba(255,0,0,1)'></td>
+ <td width='1' style='background-color: rgba(247,0,8,1)'></td>
+ <td width='1' style='background-color: rgba(239,0,16,1)'></td>
+ <td width='1' style='background-color: rgba(230,0,25,1)'></td>
+ <td width='1' style='background-color: rgba(222,0,33,1)'></td>
+ <td width='1' style='background-color: rgba(214,0,41,1)'></td>
+ <td width='1' style='background-color: rgba(206,0,49,1)'></td>
+ <td width='1' style='background-color: rgba(197,0,58,1)'></td>
+ <td width='1' style='background-color: rgba(189,0,66,1)'></td>
+ <td width='1' style='background-color: rgba(181,0,74,1)'></td>
+ <td width='1' style='background-color: rgba(173,0,82,1)'></td>
+ <td width='1' style='background-color: rgba(165,0,90,1)'></td>
+ <td width='1' style='background-color: rgba(156,0,99,1)'></td>
+ <td width='1' style='background-color: rgba(148,0,107,1)'></td>
+ <td width='1' style='background-color: rgba(140,0,115,1)'></td>
+ <td width='1' style='background-color: rgba(132,0,123,1)'></td>
+ <td width='1' style='background-color: rgba(123,0,132,1)'></td>
+ <td width='1' style='background-color: rgba(115,0,140,1)'></td>
+ <td width='1' style='background-color: rgba(107,0,148,1)'></td>
+ <td width='1' style='background-color: rgba(99,0,156,1)'></td>
+ <td width='1' style='background-color: rgba(90,0,165,1)'></td>
+ <td width='1' style='background-color: rgba(82,0,173,1)'></td>
+ <td width='1' style='background-color: rgba(74,0,181,1)'></td>
+ <td width='1' style='background-color: rgba(66,0,189,1)'></td>
+ <td width='1' style='background-color: rgba(58,0,197,1)'></td>
+ <td width='1' style='background-color: rgba(49,0,206,1)'></td>
+ <td width='1' style='background-color: rgba(41,0,214,1)'></td>
+ <td width='1' style='background-color: rgba(33,0,222,1)'></td>
+ <td width='1' style='background-color: rgba(25,0,230,1)'></td>
+ <td width='1' style='background-color: rgba(16,0,239,1)'></td>
+ <td width='1' style='background-color: rgba(8,0,247,1)'></td>
+ <td width='1' style='background-color: rgba(0,0,255,1)'></td>
+</tr>
+</table>
+</body></html>
diff --git a/image/test/reftest/pngsuite-zlib/z09n2c08.png b/image/test/reftest/pngsuite-zlib/z09n2c08.png
new file mode 100644
index 0000000000..5f191a78ee
--- /dev/null
+++ b/image/test/reftest/pngsuite-zlib/z09n2c08.png
Binary files differ
diff --git a/image/test/reftest/reftest.list b/image/test/reftest/reftest.list
new file mode 100644
index 0000000000..109a0676e1
--- /dev/null
+++ b/image/test/reftest/reftest.list
@@ -0,0 +1,55 @@
+# Check for 24-bit color mode (test for bug 414720)
+== colordepth.html about:blank
+
+# "PngSuite, the official set of PNG test images"
+# Images by Willem van Schaik
+#
+# http://www.schaik.com/pngsuite/pngsuite.html
+# http://www.libpng.org/pub/png/pngsuite.html
+include pngsuite-basic-n/reftest.list
+include pngsuite-basic-i/reftest.list
+include pngsuite-ancillary/reftest.list
+include pngsuite-background/reftest.list
+include pngsuite-chunkorder/reftest.list
+include pngsuite-corrupted/reftest.list
+include pngsuite-filtering/reftest.list
+include pngsuite-gamma/reftest.list
+include pngsuite-oddsizes/reftest.list
+include pngsuite-palettes/reftest.list
+include pngsuite-zlib/reftest.list
+
+# BMP tests
+skip-if(Android) include bmp/reftest.list
+
+# ICO tests
+skip-if(Android) include ico/reftest.list
+
+# JPEG tests
+include jpeg/reftest.list
+
+# JXL tests
+skip-if(Android||!jxl) include jxl/reftest.list
+
+# GIF tests
+include gif/reftest.list
+
+# APNG tests
+include apng/reftest.list
+
+# AVIF tests
+include avif/reftest.list
+
+# Generic image tests
+include generic/reftest.list
+
+# Color management test
+include color-management/reftest.list
+
+# Downscaling tests
+skip-if(useDrawSnapshot) include downscaling/reftest.list
+
+# Lossless encoders
+include encoders-lossless/reftest.list
+
+# webp tests
+include webp/reftest.list
diff --git a/image/test/reftest/webp/blue.png b/image/test/reftest/webp/blue.png
new file mode 100644
index 0000000000..7b62530006
--- /dev/null
+++ b/image/test/reftest/webp/blue.png
Binary files differ
diff --git a/image/test/reftest/webp/icc-bit-no-icc-chunk.webp b/image/test/reftest/webp/icc-bit-no-icc-chunk.webp
new file mode 100644
index 0000000000..66d38f46fe
--- /dev/null
+++ b/image/test/reftest/webp/icc-bit-no-icc-chunk.webp
Binary files differ
diff --git a/image/test/reftest/webp/reftest.list b/image/test/reftest/webp/reftest.list
new file mode 100644
index 0000000000..971d895a4d
--- /dev/null
+++ b/image/test/reftest/webp/reftest.list
@@ -0,0 +1 @@
+== icc-bit-no-icc-chunk.webp blue.png
diff --git a/image/test/unit/async_load_tests.js b/image/test/unit/async_load_tests.js
new file mode 100644
index 0000000000..06792349ee
--- /dev/null
+++ b/image/test/unit/async_load_tests.js
@@ -0,0 +1,298 @@
+/*
+ * Test to ensure that image loading/decoding notifications are always
+ * delivered async, and in the order we expect.
+ *
+ * Must be included from a file that has a uri of the image to test defined in
+ * var uri.
+ */
+/* import-globals-from image_load_helpers.js */
+
+const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+const ReferrerInfo = Components.Constructor(
+ "@mozilla.org/referrer-info;1",
+ "nsIReferrerInfo",
+ "init"
+);
+
+var server = new HttpServer();
+server.registerDirectory("/", do_get_file(""));
+server.registerContentType("sjs", "sjs");
+server.start(-1);
+
+load("image_load_helpers.js");
+
+var requests = [];
+/* global uri */
+
+// Return a closure that holds on to the listener from the original
+// imgIRequest, and compares its results to the cloned one.
+function getCloneStopCallback(original_listener) {
+ return function cloneStop(listener) {
+ Assert.equal(original_listener.state, listener.state);
+
+ // Sanity check to make sure we didn't accidentally use the same listener
+ // twice.
+ Assert.notEqual(original_listener, listener);
+ do_test_finished();
+ };
+}
+
+// Make sure that cloned requests get all the same callbacks as the original,
+// but they aren't synchronous right now.
+function checkClone(other_listener, aRequest) {
+ do_test_pending();
+
+ // For as long as clone notification is synchronous, we can't test the clone state reliably.
+ var listener = new ImageListener(
+ null,
+ function (foo, bar) {
+ do_test_finished();
+ } /* getCloneStopCallback(other_listener)*/
+ );
+ listener.synchronous = false;
+ var outer = Cc["@mozilla.org/image/tools;1"]
+ .getService(Ci.imgITools)
+ .createScriptedObserver(listener);
+ var clone = aRequest.clone(outer);
+ requests.push({ request: clone, locked: false });
+}
+
+// Ensure that all the callbacks were called on aRequest.
+function checkSizeAndLoad(listener, aRequest) {
+ Assert.notEqual(listener.state & SIZE_AVAILABLE, 0);
+ Assert.notEqual(listener.state & LOAD_COMPLETE, 0);
+
+ do_test_finished();
+}
+
+function secondLoadDone(oldlistener, aRequest) {
+ do_test_pending();
+
+ try {
+ var staticrequest = aRequest.getStaticRequest();
+
+ // For as long as clone notification is synchronous, we can't test the
+ // clone state reliably.
+ var listener = new ImageListener(null, checkSizeAndLoad);
+ listener.synchronous = false;
+ var outer = Cc["@mozilla.org/image/tools;1"]
+ .getService(Ci.imgITools)
+ .createScriptedObserver(listener);
+ var staticrequestclone = staticrequest.clone(outer);
+ requests.push({ request: staticrequestclone, locked: false });
+ } catch (e) {
+ // We can't create a static request. Most likely the request we started
+ // with didn't load successfully.
+ do_test_finished();
+ }
+
+ run_loadImageWithChannel_tests();
+
+ do_test_finished();
+}
+
+// Load the request a second time. This should come from the image cache, and
+// therefore would be at most risk of being served synchronously.
+function checkSecondLoad() {
+ do_test_pending();
+
+ var listener = new ImageListener(checkClone, secondLoadDone);
+ var outer = Cc["@mozilla.org/image/tools;1"]
+ .getService(Ci.imgITools)
+ .createScriptedObserver(listener);
+ var referrerInfo = new ReferrerInfo(
+ Ci.nsIReferrerInfo.NO_REFERRER_WHEN_DOWNGRADE,
+ true,
+ null
+ );
+ requests.push({
+ request: gCurrentLoader.loadImageXPCOM(
+ uri,
+ null,
+ referrerInfo,
+ null,
+ null,
+ outer,
+ null,
+ 0,
+ null
+ ),
+ locked: false,
+ });
+ listener.synchronous = false;
+}
+
+function firstLoadDone(oldlistener, aRequest) {
+ checkSecondLoad(uri);
+
+ do_test_finished();
+}
+
+// Return a closure that allows us to check the stream listener's status when the
+// image finishes loading.
+function getChannelLoadImageStopCallback(streamlistener, next) {
+ return function channelLoadStop(imglistener, aRequest) {
+ next();
+
+ do_test_finished();
+ };
+}
+
+// Load the request a second time. This should come from the image cache, and
+// therefore would be at most risk of being served synchronously.
+function checkSecondChannelLoad() {
+ do_test_pending();
+ var channel = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true });
+ var channellistener = new ChannelListener();
+ channel.asyncOpen(channellistener);
+
+ var listener = new ImageListener(
+ null,
+ getChannelLoadImageStopCallback(channellistener, all_done_callback)
+ );
+ var outer = Cc["@mozilla.org/image/tools;1"]
+ .getService(Ci.imgITools)
+ .createScriptedObserver(listener);
+ var outlistener = {};
+ requests.push({
+ request: gCurrentLoader.loadImageWithChannelXPCOM(
+ channel,
+ outer,
+ null,
+ outlistener
+ ),
+ locked: false,
+ });
+ channellistener.outputListener = outlistener.value;
+
+ listener.synchronous = false;
+}
+
+function run_loadImageWithChannel_tests() {
+ // To ensure we're testing what we expect to, create a new loader and cache.
+ gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
+ Ci.imgILoader
+ );
+
+ do_test_pending();
+ var channel = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true });
+ var channellistener = new ChannelListener();
+ channel.asyncOpen(channellistener);
+
+ var listener = new ImageListener(
+ null,
+ getChannelLoadImageStopCallback(channellistener, checkSecondChannelLoad)
+ );
+ var outer = Cc["@mozilla.org/image/tools;1"]
+ .getService(Ci.imgITools)
+ .createScriptedObserver(listener);
+ var outlistener = {};
+ requests.push({
+ request: gCurrentLoader.loadImageWithChannelXPCOM(
+ channel,
+ outer,
+ null,
+ outlistener
+ ),
+ locked: false,
+ });
+ channellistener.outputListener = outlistener.value;
+
+ listener.synchronous = false;
+}
+
+function all_done_callback() {
+ server.stop(function () {
+ do_test_finished();
+ });
+}
+
+function startImageCallback(otherCb) {
+ return function (listener, request) {
+ // Make sure we can load the same image immediately out of the cache.
+ do_test_pending();
+ var listener2 = new ImageListener(null, function (foo, bar) {
+ do_test_finished();
+ });
+ var outer = Cc["@mozilla.org/image/tools;1"]
+ .getService(Ci.imgITools)
+ .createScriptedObserver(listener2);
+ var referrerInfo = new ReferrerInfo(
+ Ci.nsIReferrerInfo.NO_REFERRER_WHEN_DOWNGRADE,
+ true,
+ null
+ );
+ requests.push({
+ request: gCurrentLoader.loadImageXPCOM(
+ uri,
+ null,
+ referrerInfo,
+ null,
+ null,
+ outer,
+ null,
+ 0,
+ null
+ ),
+ locked: false,
+ });
+ listener2.synchronous = false;
+
+ // Now that we've started another load, chain to the callback.
+ otherCb(listener, request);
+ };
+}
+
+var gCurrentLoader;
+
+function cleanup() {
+ for (let { request, locked } of requests) {
+ if (locked) {
+ try {
+ request.unlockImage();
+ } catch (e) {}
+ }
+ request.cancelAndForgetObserver(0);
+ }
+}
+
+function run_test() {
+ registerCleanupFunction(cleanup);
+
+ gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
+ Ci.imgILoader
+ );
+
+ do_test_pending();
+ var listener = new ImageListener(
+ startImageCallback(checkClone),
+ firstLoadDone
+ );
+ var outer = Cc["@mozilla.org/image/tools;1"]
+ .getService(Ci.imgITools)
+ .createScriptedObserver(listener);
+ var referrerInfo = new ReferrerInfo(
+ Ci.nsIReferrerInfo.NO_REFERRER_WHEN_DOWNGRADE,
+ true,
+ null
+ );
+ var req = gCurrentLoader.loadImageXPCOM(
+ uri,
+ null,
+ referrerInfo,
+ null,
+ null,
+ outer,
+ null,
+ 0,
+ null
+ );
+
+ // Ensure that we don't cause any mayhem when we lock an image.
+ req.lockImage();
+
+ requests.push({ request: req, locked: true });
+
+ listener.synchronous = false;
+}
diff --git a/image/test/unit/bug413512.ico b/image/test/unit/bug413512.ico
new file mode 100644
index 0000000000..b2db0429f6
--- /dev/null
+++ b/image/test/unit/bug413512.ico
Binary files differ
diff --git a/image/test/unit/bug815359.ico b/image/test/unit/bug815359.ico
new file mode 100644
index 0000000000..a24b8fb6bb
--- /dev/null
+++ b/image/test/unit/bug815359.ico
Binary files differ
diff --git a/image/test/unit/image1.png b/image/test/unit/image1.png
new file mode 100644
index 0000000000..2fb37aeec4
--- /dev/null
+++ b/image/test/unit/image1.png
Binary files differ
diff --git a/image/test/unit/image1.webp b/image/test/unit/image1.webp
new file mode 100644
index 0000000000..b2a6f92aaa
--- /dev/null
+++ b/image/test/unit/image1.webp
Binary files differ
diff --git a/image/test/unit/image1png16x16.jpg b/image/test/unit/image1png16x16.jpg
new file mode 100644
index 0000000000..488b563c90
--- /dev/null
+++ b/image/test/unit/image1png16x16.jpg
Binary files differ
diff --git a/image/test/unit/image1png64x64.jpg b/image/test/unit/image1png64x64.jpg
new file mode 100644
index 0000000000..679dad2b95
--- /dev/null
+++ b/image/test/unit/image1png64x64.jpg
Binary files differ
diff --git a/image/test/unit/image1quality50.webp b/image/test/unit/image1quality50.webp
new file mode 100644
index 0000000000..f73d615657
--- /dev/null
+++ b/image/test/unit/image1quality50.webp
Binary files differ
diff --git a/image/test/unit/image2.jpg b/image/test/unit/image2.jpg
new file mode 100644
index 0000000000..b2131bf0c1
--- /dev/null
+++ b/image/test/unit/image2.jpg
Binary files differ
diff --git a/image/test/unit/image2jpg16x16-win.png b/image/test/unit/image2jpg16x16-win.png
new file mode 100644
index 0000000000..a821626c07
--- /dev/null
+++ b/image/test/unit/image2jpg16x16-win.png
Binary files differ
diff --git a/image/test/unit/image2jpg16x16.png b/image/test/unit/image2jpg16x16.png
new file mode 100644
index 0000000000..b5b9a720a8
--- /dev/null
+++ b/image/test/unit/image2jpg16x16.png
Binary files differ
diff --git a/image/test/unit/image2jpg16x16cropped.jpg b/image/test/unit/image2jpg16x16cropped.jpg
new file mode 100644
index 0000000000..fca22cb30a
--- /dev/null
+++ b/image/test/unit/image2jpg16x16cropped.jpg
Binary files differ
diff --git a/image/test/unit/image2jpg16x16cropped2.jpg b/image/test/unit/image2jpg16x16cropped2.jpg
new file mode 100644
index 0000000000..e51d3530d3
--- /dev/null
+++ b/image/test/unit/image2jpg16x16cropped2.jpg
Binary files differ
diff --git a/image/test/unit/image2jpg16x32cropped3.jpg b/image/test/unit/image2jpg16x32cropped3.jpg
new file mode 100644
index 0000000000..13a3d26e54
--- /dev/null
+++ b/image/test/unit/image2jpg16x32cropped3.jpg
Binary files differ
diff --git a/image/test/unit/image2jpg16x32scaled.jpg b/image/test/unit/image2jpg16x32scaled.jpg
new file mode 100644
index 0000000000..6abef0f99b
--- /dev/null
+++ b/image/test/unit/image2jpg16x32scaled.jpg
Binary files differ
diff --git a/image/test/unit/image2jpg32x16cropped4.jpg b/image/test/unit/image2jpg32x16cropped4.jpg
new file mode 100644
index 0000000000..46f34918c8
--- /dev/null
+++ b/image/test/unit/image2jpg32x16cropped4.jpg
Binary files differ
diff --git a/image/test/unit/image2jpg32x16scaled.jpg b/image/test/unit/image2jpg32x16scaled.jpg
new file mode 100644
index 0000000000..e302fbafd0
--- /dev/null
+++ b/image/test/unit/image2jpg32x16scaled.jpg
Binary files differ
diff --git a/image/test/unit/image2jpg32x32-win.png b/image/test/unit/image2jpg32x32-win.png
new file mode 100644
index 0000000000..4d84df26a0
--- /dev/null
+++ b/image/test/unit/image2jpg32x32-win.png
Binary files differ
diff --git a/image/test/unit/image2jpg32x32.jpg b/image/test/unit/image2jpg32x32.jpg
new file mode 100644
index 0000000000..cf9a10a37f
--- /dev/null
+++ b/image/test/unit/image2jpg32x32.jpg
Binary files differ
diff --git a/image/test/unit/image2jpg32x32.png b/image/test/unit/image2jpg32x32.png
new file mode 100644
index 0000000000..42640cbb53
--- /dev/null
+++ b/image/test/unit/image2jpg32x32.png
Binary files differ
diff --git a/image/test/unit/image3.ico b/image/test/unit/image3.ico
new file mode 100644
index 0000000000..d44438903b
--- /dev/null
+++ b/image/test/unit/image3.ico
Binary files differ
diff --git a/image/test/unit/image3ico16x16.png b/image/test/unit/image3ico16x16.png
new file mode 100644
index 0000000000..fa61cc5046
--- /dev/null
+++ b/image/test/unit/image3ico16x16.png
Binary files differ
diff --git a/image/test/unit/image3ico32x32.png b/image/test/unit/image3ico32x32.png
new file mode 100644
index 0000000000..58a72e5c9d
--- /dev/null
+++ b/image/test/unit/image3ico32x32.png
Binary files differ
diff --git a/image/test/unit/image4.gif b/image/test/unit/image4.gif
new file mode 100644
index 0000000000..b1530bc81e
--- /dev/null
+++ b/image/test/unit/image4.gif
Binary files differ
diff --git a/image/test/unit/image4gif16x16bmp24bpp.ico b/image/test/unit/image4gif16x16bmp24bpp.ico
new file mode 100644
index 0000000000..890c81c272
--- /dev/null
+++ b/image/test/unit/image4gif16x16bmp24bpp.ico
Binary files differ
diff --git a/image/test/unit/image4gif16x16bmp32bpp.ico b/image/test/unit/image4gif16x16bmp32bpp.ico
new file mode 100644
index 0000000000..f8a9eb8adc
--- /dev/null
+++ b/image/test/unit/image4gif16x16bmp32bpp.ico
Binary files differ
diff --git a/image/test/unit/image4gif32x32bmp24bpp.ico b/image/test/unit/image4gif32x32bmp24bpp.ico
new file mode 100644
index 0000000000..28092818dc
--- /dev/null
+++ b/image/test/unit/image4gif32x32bmp24bpp.ico
Binary files differ
diff --git a/image/test/unit/image4gif32x32bmp32bpp.ico b/image/test/unit/image4gif32x32bmp32bpp.ico
new file mode 100644
index 0000000000..0e2d28c82a
--- /dev/null
+++ b/image/test/unit/image4gif32x32bmp32bpp.ico
Binary files differ
diff --git a/image/test/unit/image_load_helpers.js b/image/test/unit/image_load_helpers.js
new file mode 100644
index 0000000000..6d1e605bf5
--- /dev/null
+++ b/image/test/unit/image_load_helpers.js
@@ -0,0 +1,124 @@
+/*
+ * Helper structures to track callbacks from image and channel loads.
+ */
+
+// START_REQUEST and STOP_REQUEST are used by ChannelListener, and
+// stored in ChannelListener.requestStatus.
+const START_REQUEST = 0x01;
+const STOP_REQUEST = 0x02;
+const DATA_AVAILABLE = 0x04;
+
+// One bit per callback that imageListener below implements. Stored in
+// ImageListener.state.
+const SIZE_AVAILABLE = 0x01;
+const FRAME_UPDATE = 0x02;
+const FRAME_COMPLETE = 0x04;
+const LOAD_COMPLETE = 0x08;
+const DECODE_COMPLETE = 0x10;
+
+// Safebrowsing requires that the profile dir is set.
+do_get_profile();
+
+// An implementation of imgIScriptedNotificationObserver with the ability to
+// call specified functions on onStartRequest and onStopRequest.
+function ImageListener(start_callback, stop_callback) {
+ this.sizeAvailable = function onSizeAvailable(aRequest) {
+ Assert.ok(!this.synchronous);
+
+ this.state |= SIZE_AVAILABLE;
+
+ if (this.start_callback) {
+ this.start_callback(this, aRequest);
+ }
+ };
+ this.frameComplete = function onFrameComplete(aRequest) {
+ Assert.ok(!this.synchronous);
+
+ this.state |= FRAME_COMPLETE;
+ };
+ this.decodeComplete = function onDecodeComplete(aRequest) {
+ Assert.ok(!this.synchronous);
+
+ this.state |= DECODE_COMPLETE;
+ };
+ this.loadComplete = function onLoadcomplete(aRequest) {
+ Assert.ok(!this.synchronous);
+
+ this.state |= LOAD_COMPLETE;
+
+ if (this.stop_callback) {
+ this.stop_callback(this, aRequest);
+ }
+ };
+ this.frameUpdate = function onFrameUpdate(aRequest) {};
+ this.isAnimated = function onIsAnimated() {};
+
+ // Initialize the synchronous flag to true to start. This must be set to
+ // false before exiting to the event loop!
+ this.synchronous = true;
+
+ // A function to call when onStartRequest is called.
+ this.start_callback = start_callback;
+
+ // A function to call when onStopRequest is called.
+ this.stop_callback = stop_callback;
+
+ // The image load/decode state.
+ // A bitfield that tracks which callbacks have been called. Takes the bits
+ // defined above.
+ this.state = 0;
+}
+
+function NS_FAILED(val) {
+ return !!(val & 0x80000000);
+}
+
+function ChannelListener() {
+ this.onStartRequest = function onStartRequest(aRequest) {
+ if (this.outputListener) {
+ this.outputListener.onStartRequest(aRequest);
+ }
+
+ this.requestStatus |= START_REQUEST;
+ };
+
+ this.onDataAvailable = function onDataAvailable(
+ aRequest,
+ aInputStream,
+ aOffset,
+ aCount
+ ) {
+ if (this.outputListener) {
+ this.outputListener.onDataAvailable(
+ aRequest,
+ aInputStream,
+ aOffset,
+ aCount
+ );
+ }
+
+ this.requestStatus |= DATA_AVAILABLE;
+ };
+
+ this.onStopRequest = function onStopRequest(aRequest, aStatusCode) {
+ if (this.outputListener) {
+ this.outputListener.onStopRequest(aRequest, aStatusCode);
+ }
+
+ // If we failed (or were canceled - failure is implied if canceled),
+ // there's no use tracking our state, since it's meaningless.
+ if (NS_FAILED(aStatusCode)) {
+ this.requestStatus = 0;
+ } else {
+ this.requestStatus |= STOP_REQUEST;
+ }
+ };
+
+ // A listener to pass the notifications we get to.
+ this.outputListener = null;
+
+ // The request's status. A bitfield that holds one or both of START_REQUEST
+ // and STOP_REQUEST, according to which callbacks have been called on the
+ // associated request.
+ this.requestStatus = 0;
+}
diff --git a/image/test/unit/test_async_notification.js b/image/test/unit/test_async_notification.js
new file mode 100644
index 0000000000..3f5f47c271
--- /dev/null
+++ b/image/test/unit/test_async_notification.js
@@ -0,0 +1,15 @@
+/*
+ * Test for asynchronous image load/decode notifications in the case that the image load works.
+ */
+
+// A simple 3x3 png; rows go red, green, blue. Stolen from the PNG encoder test.
+
+var pngspec =
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=";
+var ioService = Services.io;
+
+// This is used in async_load_tests.js
+/* exported uri */
+var uri = ioService.newURI(pngspec);
+
+load("async_load_tests.js");
diff --git a/image/test/unit/test_async_notification_404.js b/image/test/unit/test_async_notification_404.js
new file mode 100644
index 0000000000..c8aab9fe1d
--- /dev/null
+++ b/image/test/unit/test_async_notification_404.js
@@ -0,0 +1,23 @@
+/*
+ * Test to ensure that load/decode notifications are delivered completely and
+ * asynchronously when dealing with a file that's a 404.
+ */
+/* import-globals-from async_load_tests.js */
+
+const { XPCOMUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/XPCOMUtils.sys.mjs"
+);
+
+var ioService = Services.io;
+
+// This is used in async_load_tests.js
+// eslint-disable-next-line no-unused-vars
+XPCOMUtils.defineLazyGetter(this, "uri", function () {
+ return ioService.newURI(
+ "http://localhost:" +
+ server.identity.primaryPort +
+ "/async-notification-never-here.jpg"
+ );
+});
+
+load("async_load_tests.js");
diff --git a/image/test/unit/test_async_notification_animated.js b/image/test/unit/test_async_notification_animated.js
new file mode 100644
index 0000000000..f201f90f60
--- /dev/null
+++ b/image/test/unit/test_async_notification_animated.js
@@ -0,0 +1,19 @@
+/*
+ * Test for asynchronous image load/decode notifications in the case that the
+ * image load works, but for an animated image.
+ *
+ * If this fails because a request wasn't cancelled, it's possible that
+ * imgContainer::ExtractFrame didn't set the new image's status correctly.
+ */
+
+// transparent-animation.gif from the gif reftests.
+
+var spec =
+ "data:image/gif;base64,R0lGODlhZABkAIABAP8AAP///yH5BAkBAAEALAAAAABLAGQAAAK8jI+py+0Po5y02ouz3rz7D4biSJbmiabqyrbuC8fyTNf2jef6zvf+DwwKh8Si8YhMKpchgPMJjUqnVOipis1ir9qul+sNV8HistVkTj/JajG7/UXDy+95tm4fy/NdPF/q93dWIqgVWAhwWKgoyPjnyAeZJ2lHOWcJh9mmqcaZ5mkGSreHOCXqRloadRrGGkeoapoa6+TaN0tra4gbq3vHq+q7BVwqrMeEnKy8zNzs/AwdLT1NXW19jZ1tUgAAIfkECQEAAQAsAAAAADQAZAAAArCMj6nL7Q+jnLTai7PevPsPhuJIluaJpurKtu4Lx/JM1/aN5/rO9/7vAAiHxKLxiCRCkswmc+mMSqHSapJqzSof2u4Q67WCw1MuOTs+N9Pqq7kdZcON8vk2aF+/88g6358HaCc4Rwhn2IaopnjGSOYYBukl2UWpZYm2x0enuXnX4NnXGQqAKTYaalqlWoZH+snwWsQah+pJ64Sr5ypbCvQLHCw8TFxsfIycrLzM3PxQAAAh+QQJAQABACwAAAAAGwBkAAACUIyPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gTE8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvdrfYnH5LL5jE6r16sCADs=";
+var ioService = Services.io;
+
+// This is used in async_load_tests.js
+/* exported uri */
+var uri = ioService.newURI(spec);
+
+load("async_load_tests.js");
diff --git a/image/test/unit/test_encoder_apng.js b/image/test/unit/test_encoder_apng.js
new file mode 100644
index 0000000000..f055a0335f
--- /dev/null
+++ b/image/test/unit/test_encoder_apng.js
@@ -0,0 +1,582 @@
+/*
+ * Test for APNG encoding in ImageLib
+ *
+ */
+
+// dispose=[none|background|previous]
+// blend=[source|over]
+
+var apng1A = {
+ // A 3x3 image with 3 frames, alternating red, green, blue. RGB format.
+ width: 3,
+ height: 3,
+ skipFirstFrame: false,
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGB,
+ transparency: null,
+ plays: 0,
+
+ frames: [
+ {
+ // frame #1
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGB,
+ stride: 9,
+ transparency: null,
+
+ pixels: [
+ 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
+ 0, 0, 255, 0, 0, 255, 0, 0,
+ ],
+ },
+
+ {
+ // frame #2
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGB,
+ stride: 9,
+ transparency: null,
+
+ pixels: [
+ 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0,
+ 255, 0, 0, 255, 0, 0, 255, 0,
+ ],
+ },
+
+ {
+ // frame #3
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGB,
+ stride: 9,
+ transparency: null,
+
+ pixels: [
+ 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0,
+ 255, 0, 0, 255, 0, 0, 255,
+ ],
+ },
+ ],
+ expected:
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAAA9JREFUCFtj/M8ABYxYWAA5IQMBD9nE1QAAABpmY1RMAAAAAQAAAAMAAAADAAAAAAAAAAAB9APoAADuZcrMAAAAFGZkQVQAAAACCFtjZPjPAAGMWFgANiQDAVBdoI8AAAAaZmNUTAAAAAMAAAADAAAAAwAAAAAAAAAAAfQD6AAAA/MZJQAAABVmZEFUAAAABAhbY2Rg+M8ABoxYWAAzJwMBWk5KPwAAAABJRU5ErkJggg==",
+};
+
+var apng1B = {
+ // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format.
+ width: 3,
+ height: 3,
+ skipFirstFrame: false,
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ transparency: null,
+ plays: 0,
+
+ frames: [
+ {
+ // frame #1
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
+ 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255,
+ ],
+ },
+
+ {
+ // frame #2
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+ 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+ ],
+ },
+
+ {
+ // frame #3
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0,
+ 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255,
+ 255,
+ ],
+ },
+ ],
+ expected:
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABJJREFUCFtj/M/AAEQQwIiTAwCM6AX+t+X3FQAAABpmY1RMAAAAAQAAAAMAAAADAAAAAAAAAAAB9APoAADuZcrMAAAAFWZkQVQAAAACCFtjZPgPhFDAiJMDAInrBf4Q0nfOAAAAGmZjVEwAAAADAAAAAwAAAAMAAAAAAAAAAAH0A+gAAAPzGSUAAAAWZmRBVAAAAAQIW2NkYPj/nwEKGHFyAIbuBf50PCpiAAAAAElFTkSuQmCC",
+};
+
+var apng1C = {
+ // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format.
+ // The first frame is skipped, so it will only flash green/blue (or static red in an APNG-unaware viewer)
+ width: 3,
+ height: 3,
+ skipFirstFrame: true,
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ transparency: null,
+ plays: 0,
+
+ frames: [
+ {
+ // frame #1
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
+ 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255,
+ ],
+ },
+
+ {
+ // frame #2
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+ 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+ ],
+ },
+
+ {
+ // frame #3
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0,
+ 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255,
+ 255,
+ ],
+ },
+ ],
+ expected:
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAACAAAAAPONk3AAAAASSURBVAhbY/zPwABEEMCIkwMAjOgF/rfl9xUAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABVmZEFUAAAAAQhbY2T4D4RQwIiTAwCJ6wX++lSqrAAAABpmY1RMAAAAAgAAAAMAAAADAAAAAAAAAAAB9APoAACYgPPxAAAAFmZkQVQAAAADCFtjZGD4/58BChhxcgCG7gX+PgKhKQAAAABJRU5ErkJggg==",
+};
+
+var apng2A = {
+ // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format.
+ // blend = over mode
+ // (The green frame is a horizontal gradient, and the blue frame is a
+ // vertical gradient. They stack as they animate.)
+ width: 3,
+ height: 3,
+ skipFirstFrame: false,
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ transparency: null,
+ plays: 0,
+
+ frames: [
+ {
+ // frame #1
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
+ 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255,
+ ],
+ },
+
+ {
+ // frame #2
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "over",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 0, 255, 0, 255, 0, 255, 0, 180, 0, 255, 0, 75, 0, 255, 0, 255, 0, 255,
+ 0, 180, 0, 255, 0, 75, 0, 255, 0, 255, 0, 255, 0, 180, 0, 255, 0, 75,
+ ],
+ },
+
+ {
+ // frame #3
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "over",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 0, 0, 255, 75, 0, 0, 255, 75, 0, 0, 255, 75, 0, 0, 255, 180, 0, 0, 255,
+ 180, 0, 0, 255, 180, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255,
+ ],
+ },
+ ],
+ expected:
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABJJREFUCFtj/M/AAEQQwIiTAwCM6AX+t+X3FQAAABpmY1RMAAAAAQAAAAMAAAADAAAAAAAAAAAB9APoAAGZYvpaAAAAGWZkQVQAAAACCFtjZPgPhAwMW4F4OiNODgDI3wnis0vjTAAAABpmY1RMAAAAAwAAAAMAAAADAAAAAAAAAAAB9APoAAF09CmzAAAAHGZkQVQAAAAECFtjZGD4780ABYxAzhZkzn8YBwBn4AT/ernr+wAAAABJRU5ErkJggg==",
+};
+
+var apng2B = {
+ // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format.
+ // blend = over, dispose = background
+ // (The green frame is a horizontal gradient, and the blue frame is a
+ // vertical gradient. Each frame is displayed individually, blended to
+ // whatever the background is.)
+ width: 3,
+ height: 3,
+ skipFirstFrame: false,
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ transparency: null,
+ plays: 0,
+
+ frames: [
+ {
+ // frame #1
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "background",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
+ 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255,
+ ],
+ },
+
+ {
+ // frame #2
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "background",
+ blend: "over",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 0, 255, 0, 255, 0, 255, 0, 180, 0, 255, 0, 75, 0, 255, 0, 255, 0, 255,
+ 0, 180, 0, 255, 0, 75, 0, 255, 0, 255, 0, 255, 0, 180, 0, 255, 0, 75,
+ ],
+ },
+
+ {
+ // frame #3
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "background",
+ blend: "over",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 0, 0, 255, 75, 0, 0, 255, 75, 0, 0, 255, 75, 0, 0, 255, 180, 0, 0, 255,
+ 180, 0, 0, 255, 180, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255,
+ ],
+ },
+ ],
+ expected:
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AEAbA0RWQAAABJJREFUCFtj/M/AAEQQwIiTAwCM6AX+t+X3FQAAABpmY1RMAAAAAQAAAAMAAAADAAAAAAAAAAAB9APoAQGAecsbAAAAGWZkQVQAAAACCFtjZPgPhAwMW4F4OiNODgDI3wnis0vjTAAAABpmY1RMAAAAAwAAAAMAAAADAAAAAAAAAAAB9APoAQFt7xjyAAAAHGZkQVQAAAAECFtjZGD4780ABYxAzhZkzn8YBwBn4AT/ernr+wAAAABJRU5ErkJggg==",
+};
+
+var apng3 = {
+ // A 3x3 image with 4 frames. First frame is white, then 1x1 frames draw a diagonal line
+ width: 3,
+ height: 3,
+ skipFirstFrame: false,
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ transparency: null,
+ plays: 0,
+
+ frames: [
+ {
+ // frame #1
+ width: 3,
+ height: 3,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ ],
+ },
+
+ {
+ // frame #2
+ width: 1,
+ height: 1,
+ x_offset: 0,
+ y_offset: 0,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [0, 0, 0, 255],
+ },
+
+ {
+ // frame #3
+ width: 1,
+ height: 1,
+ x_offset: 1,
+ y_offset: 1,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [0, 0, 0, 255],
+ },
+
+ {
+ // frame #4
+ width: 1,
+ height: 1,
+ x_offset: 2,
+ y_offset: 2,
+ dispose: "none",
+ blend: "source",
+ delay: 500,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [0, 0, 0, 255],
+ },
+ ],
+
+ expected:
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAAEAAAAAHzNZtAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABFJREFUCFtj/A8EDFDAiJMDABlqC/jamhxvAAAAGmZjVEwAAAABAAAAAQAAAAEAAAAAAAAAAAH0A+gAADJXfawAAAARZmRBVAAAAAIIW2NgYGD4DwABBAEA0iEgKQAAABpmY1RMAAAAAwAAAAEAAAABAAAAAQAAAAEB9APoAAC4OHoxAAAAEWZkQVQAAAAECFtjYGBg+A8AAQQBACrja58AAAAaZmNUTAAAAAUAAAABAAAAAQAAAAIAAAACAfQD6AAA/fh01wAAABFmZEFUAAAABghbY2BgYPgPAAEEAQDLja8yAAAAAElFTkSuQmCC",
+};
+
+// Main test entry point.
+function run_test() {
+ dump("Checking apng1A...\n");
+ run_test_for(apng1A);
+ dump("Checking apng1B...\n");
+ run_test_for(apng1B);
+ dump("Checking apng1C...\n");
+ run_test_for(apng1C);
+
+ dump("Checking apng2A...\n");
+ run_test_for(apng2A);
+ dump("Checking apng2B...\n");
+ run_test_for(apng2B);
+
+ dump("Checking apng3...\n");
+ run_test_for(apng3);
+}
+
+function run_test_for(input) {
+ var encoder, dataURL;
+
+ encoder = encodeImage(input);
+ dataURL = makeDataURL(encoder, "image/png");
+ Assert.equal(dataURL, input.expected);
+}
+
+function encodeImage(input) {
+ var encoder =
+ Cc["@mozilla.org/image/encoder;2?type=image/png"].createInstance();
+ encoder.QueryInterface(Ci.imgIEncoder);
+
+ var options = "";
+ if (input.transparency) {
+ options += "transparency=" + input.transparency;
+ }
+ options += ";frames=" + input.frames.length;
+ options += ";skipfirstframe=" + (input.skipFirstFrame ? "yes" : "no");
+ options += ";plays=" + input.plays;
+ encoder.startImageEncode(input.width, input.height, input.format, options);
+
+ for (var i = 0; i < input.frames.length; i++) {
+ var frame = input.frames[i];
+
+ options = "";
+ if (frame.transparency) {
+ options += "transparency=" + input.transparency;
+ }
+ options += ";delay=" + frame.delay;
+ options += ";dispose=" + frame.dispose;
+ options += ";blend=" + frame.blend;
+ if (frame.x_offset > 0) {
+ options += ";xoffset=" + frame.x_offset;
+ }
+ if (frame.y_offset > 0) {
+ options += ";yoffset=" + frame.y_offset;
+ }
+
+ encoder.addImageFrame(
+ frame.pixels,
+ frame.pixels.length,
+ frame.width,
+ frame.height,
+ frame.stride,
+ frame.format,
+ options
+ );
+ }
+
+ encoder.endImageEncode();
+
+ return encoder;
+}
+
+function makeDataURL(encoder, mimetype) {
+ var rawStream = encoder.QueryInterface(Ci.nsIInputStream);
+
+ var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance();
+ stream.QueryInterface(Ci.nsIBinaryInputStream);
+
+ stream.setInputStream(rawStream);
+
+ var bytes = stream.readByteArray(stream.available()); // returns int[]
+
+ var base64String = toBase64(bytes);
+
+ return "data:" + mimetype + ";base64," + base64String;
+}
+
+/* toBase64 copied from extensions/xml-rpc/src/nsXmlRpcClient.js */
+
+/* Convert data (an array of integers) to a Base64 string. */
+const toBase64Table =
+ // eslint-disable-next-line no-useless-concat
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789+/";
+const base64Pad = "=";
+function toBase64(data) {
+ var result = "";
+ var length = data.length;
+ var i;
+ // Convert every three bytes to 4 ascii characters.
+ for (i = 0; i < length - 2; i += 3) {
+ result += toBase64Table[data[i] >> 2];
+ result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
+ result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
+ result += toBase64Table[data[i + 2] & 0x3f];
+ }
+
+ // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
+ if (length % 3) {
+ i = length - (length % 3);
+ result += toBase64Table[data[i] >> 2];
+ if (length % 3 == 2) {
+ result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
+ result += toBase64Table[(data[i + 1] & 0x0f) << 2];
+ result += base64Pad;
+ } else {
+ result += toBase64Table[(data[i] & 0x03) << 4];
+ result += base64Pad + base64Pad;
+ }
+ }
+
+ return result;
+}
diff --git a/image/test/unit/test_encoder_png.js b/image/test/unit/test_encoder_png.js
new file mode 100644
index 0000000000..73e91f573f
--- /dev/null
+++ b/image/test/unit/test_encoder_png.js
@@ -0,0 +1,263 @@
+/*
+ * Test for PNG encoding in ImageLib
+ *
+ */
+
+var png1A = {
+ // A 3x3 image, rows are red, green, blue.
+ // RGB format, transparency defaults.
+
+ transparency: null,
+
+ frames: [
+ {
+ width: 3,
+ height: 3,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGB,
+ stride: 9,
+
+ pixels: [
+ 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0,
+ 255, 0, 0, 255, 0, 0, 255,
+ ],
+ },
+ ],
+ expected:
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAFElEQVQIW2P8zwAFjAwwJiMDjAkANiQDAUpvlioAAAAASUVORK5CYII=",
+};
+
+var png1B = {
+ // A 3x3 image, rows are red, green, blue.
+ // RGB format, transparency=none.
+
+ transparency: "none",
+
+ frames: [
+ {
+ width: 3,
+ height: 3,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGB,
+ stride: 9,
+
+ pixels: [
+ 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0,
+ 255, 0, 0, 255, 0, 0, 255,
+ ],
+ },
+ ],
+ expected:
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAFElEQVQIW2P8zwAFjAwwJiMDjAkANiQDAUpvlioAAAAASUVORK5CYII=",
+};
+
+var png2A = {
+ // A 3x3 image, rows are: red, green, blue. Columns are: 0%, 33%, 66% transparent.
+
+ transparency: null,
+
+ frames: [
+ {
+ width: 3,
+ height: 3,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 255, 0, 0, 255, 255, 0, 0, 170, 255, 0, 0, 85, 0, 255, 0, 255, 0, 255,
+ 0, 170, 0, 255, 0, 85, 0, 0, 255, 255, 0, 0, 255, 170, 0, 0, 255, 85,
+ ],
+ },
+ ],
+ expected:
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAAGUlEQVQIW2P8z8AARAyrQZgRyETiMPyHcwDKCwoAGxxLEQAAAABJRU5ErkJggg==",
+};
+
+var png2B = {
+ // A 3x3 image, rows are: red, green, blue. Columns are: 0%, 33%, 66% transparent,
+ // but transparency will be ignored.
+
+ transparency: "none",
+
+ frames: [
+ {
+ width: 3,
+ height: 3,
+
+ format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+ stride: 12,
+
+ pixels: [
+ 255, 0, 0, 255, 255, 0, 0, 170, 255, 0, 0, 85, 0, 255, 0, 255, 0, 255,
+ 0, 170, 0, 255, 0, 85, 0, 0, 255, 255, 0, 0, 255, 170, 0, 0, 255, 85,
+ ],
+ },
+ ],
+ expected:
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAFElEQVQIW2P8zwAFjAwwJiMDjAkANiQDAUpvlioAAAAASUVORK5CYII=",
+};
+
+// Main test entry point.
+function run_test() {
+ dump("Checking png1A...\n");
+ run_test_for(png1A);
+ dump("Checking png1B...\n");
+ run_test_for(png1B);
+ dump("Checking png2A...\n");
+ run_test_for(png2A);
+ dump("Checking png2B...\n");
+ run_test_for(png2B);
+}
+
+function run_test_for(input) {
+ var encoder, dataURL;
+
+ encoder = encodeImage(input);
+ dataURL = makeDataURL(encoder, "image/png");
+ Assert.equal(dataURL, input.expected);
+
+ encoder = encodeImageAsync(input);
+ dataURL = makeDataURLFromAsync(encoder, "image/png", input.expected);
+}
+
+function encodeImage(input) {
+ var encoder =
+ Cc["@mozilla.org/image/encoder;2?type=image/png"].createInstance();
+ encoder.QueryInterface(Ci.imgIEncoder);
+
+ var options = "";
+ if (input.transparency) {
+ options += "transparency=" + input.transparency;
+ }
+
+ var frame = input.frames[0];
+ encoder.initFromData(
+ frame.pixels,
+ frame.pixels.length,
+ frame.width,
+ frame.height,
+ frame.stride,
+ frame.format,
+ options
+ );
+ return encoder;
+}
+
+function _encodeImageAsyncFactory(frame, options, encoder) {
+ function finishEncode() {
+ encoder.addImageFrame(
+ frame.pixels,
+ frame.pixels.length,
+ frame.width,
+ frame.height,
+ frame.stride,
+ frame.format,
+ options
+ );
+ encoder.endImageEncode();
+ }
+ return finishEncode;
+}
+
+function encodeImageAsync(input) {
+ var encoder =
+ Cc["@mozilla.org/image/encoder;2?type=image/png"].createInstance();
+ encoder.QueryInterface(Ci.imgIEncoder);
+
+ var options = "";
+ if (input.transparency) {
+ options += "transparency=" + input.transparency;
+ }
+
+ var frame = input.frames[0];
+ encoder.startImageEncode(frame.width, frame.height, frame.format, options);
+
+ do_timeout(50, _encodeImageAsyncFactory(frame, options, encoder));
+ return encoder;
+}
+
+function makeDataURL(encoder, mimetype) {
+ var rawStream = encoder.QueryInterface(Ci.nsIInputStream);
+
+ var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance();
+ stream.QueryInterface(Ci.nsIBinaryInputStream);
+
+ stream.setInputStream(rawStream);
+
+ var bytes = stream.readByteArray(stream.available()); // returns int[]
+
+ var base64String = toBase64(bytes);
+
+ return "data:" + mimetype + ";base64," + base64String;
+}
+
+function makeDataURLFromAsync(encoder, mimetype, expected) {
+ do_test_pending();
+ var rawStream = encoder.QueryInterface(Ci.nsIAsyncInputStream);
+
+ var currentThread =
+ Cc["@mozilla.org/thread-manager;1"].getService().currentThread;
+
+ var bytes = [];
+
+ var binarystream = Cc["@mozilla.org/binaryinputstream;1"].createInstance();
+ binarystream.QueryInterface(Ci.nsIBinaryInputStream);
+
+ var asyncReader = {
+ onInputStreamReady(stream) {
+ binarystream.setInputStream(stream);
+ var available = 0;
+ try {
+ available = stream.available();
+ } catch (e) {}
+
+ if (available > 0) {
+ bytes = bytes.concat(binarystream.readByteArray(available));
+ stream.asyncWait(this, 0, 0, currentThread);
+ } else {
+ var base64String = toBase64(bytes);
+ var dataURL = "data:" + mimetype + ";base64," + base64String;
+ Assert.equal(dataURL, expected);
+ do_test_finished();
+ }
+ },
+ };
+ rawStream.asyncWait(asyncReader, 0, 0, currentThread);
+}
+
+/* toBase64 copied from extensions/xml-rpc/src/nsXmlRpcClient.js */
+
+/* Convert data (an array of integers) to a Base64 string. */
+const toBase64Table =
+ // eslint-disable-next-line no-useless-concat
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789+/";
+const base64Pad = "=";
+function toBase64(data) {
+ var result = "";
+ var length = data.length;
+ var i;
+ // Convert every three bytes to 4 ascii characters.
+ for (i = 0; i < length - 2; i += 3) {
+ result += toBase64Table[data[i] >> 2];
+ result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
+ result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
+ result += toBase64Table[data[i + 2] & 0x3f];
+ }
+
+ // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
+ if (length % 3) {
+ i = length - (length % 3);
+ result += toBase64Table[data[i] >> 2];
+ if (length % 3 == 2) {
+ result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
+ result += toBase64Table[(data[i + 1] & 0x0f) << 2];
+ result += base64Pad;
+ } else {
+ result += toBase64Table[(data[i] & 0x03) << 4];
+ result += base64Pad + base64Pad;
+ }
+ }
+
+ return result;
+}
diff --git a/image/test/unit/test_imgtools.js b/image/test/unit/test_imgtools.js
new file mode 100644
index 0000000000..7f832a6b12
--- /dev/null
+++ b/image/test/unit/test_imgtools.js
@@ -0,0 +1,869 @@
+/*
+ * Tests for imgITools
+ */
+
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+
+/*
+ * dumpToFile()
+ *
+ * For test development, dumps the specified array to a file.
+ * Call |dumpToFile(outData);| in a test to file to a file.
+ */
+// eslint-disable-next-line no-unused-vars
+function dumpToFile(aData) {
+ var outputFile = do_get_cwd();
+ outputFile.append("testdump.webp");
+
+ var outputStream = Cc[
+ "@mozilla.org/network/file-output-stream;1"
+ ].createInstance(Ci.nsIFileOutputStream);
+ // WR_ONLY|CREATE|TRUNC
+ outputStream.init(outputFile, 0x02 | 0x08 | 0x20, 0o644, null);
+
+ var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(
+ Ci.nsIBinaryOutputStream
+ );
+ bos.setOutputStream(outputStream);
+
+ bos.writeByteArray(aData);
+
+ outputStream.close();
+}
+
+/*
+ * getFileInputStream()
+ *
+ * Returns an input stream for the specified file.
+ */
+function getFileInputStream(aFile) {
+ var inputStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ // init the stream as RD_ONLY, -1 == default permissions.
+ inputStream.init(aFile, 0x01, -1, null);
+
+ // Blah. The image decoders use ReadSegments, which isn't implemented on
+ // file input streams. Use a buffered stream to make it work.
+ var bis = Cc["@mozilla.org/network/buffered-input-stream;1"].createInstance(
+ Ci.nsIBufferedInputStream
+ );
+ bis.init(inputStream, 1024);
+
+ return bis;
+}
+
+/*
+ * streamToArray()
+ *
+ * Consumes an input stream, and returns its bytes as an array.
+ */
+function streamToArray(aStream) {
+ var size = aStream.available();
+
+ // use a binary input stream to grab the bytes.
+ var bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
+ Ci.nsIBinaryInputStream
+ );
+ bis.setInputStream(aStream);
+
+ var bytes = bis.readByteArray(size);
+ if (size != bytes.length) {
+ throw new Error("Didn't read expected number of bytes");
+ }
+
+ return bytes;
+}
+
+/*
+ * compareArrays
+ *
+ * Compares two arrays, and throws if there's a difference.
+ */
+function compareArrays(aArray1, aArray2) {
+ Assert.equal(aArray1.length, aArray2.length);
+
+ for (var i = 0; i < aArray1.length; i++) {
+ if (aArray1[i] != aArray2[i]) {
+ throw new Error("arrays differ at index " + i);
+ }
+ }
+}
+
+/*
+ * checkExpectedError
+ *
+ * Checks to see if a thrown error was expected or not, and if it
+ * matches the expected value.
+ */
+function checkExpectedError(aExpectedError, aActualError) {
+ if (aExpectedError) {
+ if (!aActualError) {
+ throw new Error("Didn't throw as expected (" + aExpectedError + ")");
+ }
+
+ if (!aExpectedError.test(aActualError)) {
+ throw new Error("Threw (" + aActualError + "), not (" + aExpectedError);
+ }
+
+ // We got the expected error, so make a note in the test log.
+ dump("...that error was expected.\n\n");
+ } else if (aActualError) {
+ throw new Error("Threw unexpected error: " + aActualError);
+ }
+}
+
+function run_test() {
+ try {
+ /* ========== 0 ========== */
+ var testnum = 0;
+ var testdesc = "imgITools setup";
+ var err = null;
+
+ var imgTools = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools);
+
+ if (!imgTools) {
+ throw new Error("Couldn't get imgITools service");
+ }
+
+ // Ugh, this is an ugly hack. The pixel values we get in Windows are sometimes
+ // +/- 1 value compared to other platforms, so we need to compare against a
+ // different set of reference images. nsIXULRuntime.OS doesn't seem to be
+ // available in xpcshell, so we'll use this as a kludgy way to figure out if
+ // we're running on Windows.
+ var isWindows = mozinfo.os == "win";
+
+ /* ========== 1 ========== */
+ testnum++;
+ testdesc = "test decoding a PNG";
+
+ // 64x64 png, 8415 bytes.
+ var imgName = "image1.png";
+ var inMimeType = "image/png";
+ var imgFile = do_get_file(imgName);
+
+ var istream = getFileInputStream(imgFile);
+ Assert.equal(istream.available(), 8415);
+
+ var buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ var container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ inMimeType
+ );
+
+ // It's not easy to look at the pixel values from JS, so just
+ // check the container's size.
+ Assert.equal(container.width, 64);
+ Assert.equal(container.height, 64);
+
+ /* ========== 2 ========== */
+ testnum++;
+ testdesc = "test encoding a scaled JPEG";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeScaledImage(container, "image/jpeg", 16, 16);
+
+ var encodedBytes = streamToArray(istream);
+ // Get bytes for expected result
+ var refName = "image1png16x16.jpg";
+ var refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 1050);
+ var referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 3 ========== */
+ testnum++;
+ testdesc = "test encoding an unscaled JPEG";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeImage(container, "image/jpeg");
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image1png64x64.jpg";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 4507);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 4 ========== */
+ testnum++;
+ testdesc = "test decoding a JPEG";
+
+ // 32x32 jpeg, 3494 bytes.
+ imgName = "image2.jpg";
+ inMimeType = "image/jpeg";
+ imgFile = do_get_file(imgName);
+
+ istream = getFileInputStream(imgFile);
+ Assert.equal(istream.available(), 3494);
+
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ inMimeType
+ );
+
+ // It's not easy to look at the pixel values from JS, so just
+ // check the container's size.
+ Assert.equal(container.width, 32);
+ Assert.equal(container.height, 32);
+
+ /* ========== 5 ========== */
+ testnum++;
+ testdesc = "test encoding a scaled PNG";
+
+ if (!isWindows) {
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeScaledImage(container, "image/png", 16, 16);
+
+ encodedBytes = streamToArray(istream);
+ // Get bytes for expected result
+ refName = isWindows ? "image2jpg16x16-win.png" : "image2jpg16x16.png";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 955);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+ }
+
+ /* ========== 6 ========== */
+ testnum++;
+ testdesc = "test encoding an unscaled PNG";
+
+ if (!isWindows) {
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeImage(container, "image/png");
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = isWindows ? "image2jpg32x32-win.png" : "image2jpg32x32.png";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 3026);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+ }
+
+ /* ========== 7 ========== */
+ testnum++;
+ testdesc = "test decoding a ICO";
+
+ // 16x16 ico, 1406 bytes.
+ imgName = "image3.ico";
+ inMimeType = "image/x-icon";
+ imgFile = do_get_file(imgName);
+
+ istream = getFileInputStream(imgFile);
+ Assert.equal(istream.available(), 1406);
+
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ inMimeType
+ );
+
+ // It's not easy to look at the pixel values from JS, so just
+ // check the container's size.
+ Assert.equal(container.width, 16);
+ Assert.equal(container.height, 16);
+
+ /* ========== 8 ========== */
+ testnum++;
+ testdesc = "test encoding a scaled PNG"; // note that we're scaling UP
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeScaledImage(container, "image/png", 32, 32);
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image3ico32x32.png";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 2280);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 9 ========== */
+ testnum++;
+ testdesc = "test encoding an unscaled PNG";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeImage(container, "image/png");
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image3ico16x16.png";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 520);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 10 ========== */
+ testnum++;
+ testdesc = "test decoding a GIF";
+
+ // 32x32 gif, 1809 bytes.
+ imgName = "image4.gif";
+ inMimeType = "image/gif";
+ imgFile = do_get_file(imgName);
+
+ istream = getFileInputStream(imgFile);
+ Assert.equal(istream.available(), 1809);
+
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ inMimeType
+ );
+
+ // It's not easy to look at the pixel values from JS, so just
+ // check the container's size.
+ Assert.equal(container.width, 32);
+ Assert.equal(container.height, 32);
+
+ /* ========== 11 ========== */
+ testnum++;
+ testdesc =
+ "test encoding an unscaled ICO with format options " +
+ "(format=bmp;bpp=32)";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeImage(
+ container,
+ "image/vnd.microsoft.icon",
+ "format=bmp;bpp=32"
+ );
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image4gif32x32bmp32bpp.ico";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 4286);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 12 ========== */
+ testnum++;
+ testdesc =
+ // eslint-disable-next-line no-useless-concat
+ "test encoding a scaled ICO with format options " + "(format=bmp;bpp=32)";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeScaledImage(
+ container,
+ "image/vnd.microsoft.icon",
+ 16,
+ 16,
+ "format=bmp;bpp=32"
+ );
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image4gif16x16bmp32bpp.ico";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 1150);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 13 ========== */
+ testnum++;
+ testdesc =
+ "test encoding an unscaled ICO with format options " +
+ "(format=bmp;bpp=24)";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeImage(
+ container,
+ "image/vnd.microsoft.icon",
+ "format=bmp;bpp=24"
+ );
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image4gif32x32bmp24bpp.ico";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 3262);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 14 ========== */
+ testnum++;
+ testdesc =
+ // eslint-disable-next-line no-useless-concat
+ "test encoding a scaled ICO with format options " + "(format=bmp;bpp=24)";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeScaledImage(
+ container,
+ "image/vnd.microsoft.icon",
+ 16,
+ 16,
+ "format=bmp;bpp=24"
+ );
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image4gif16x16bmp24bpp.ico";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 894);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 15 ========== */
+ testnum++;
+ testdesc = "test cropping a JPG";
+
+ // 32x32 jpeg, 3494 bytes.
+ imgName = "image2.jpg";
+ inMimeType = "image/jpeg";
+ imgFile = do_get_file(imgName);
+
+ istream = getFileInputStream(imgFile);
+ Assert.equal(istream.available(), 3494);
+
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ inMimeType
+ );
+
+ // It's not easy to look at the pixel values from JS, so just
+ // check the container's size.
+ Assert.equal(container.width, 32);
+ Assert.equal(container.height, 32);
+
+ // encode a cropped image
+ istream = imgTools.encodeCroppedImage(
+ container,
+ "image/jpeg",
+ 0,
+ 0,
+ 16,
+ 16
+ );
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image2jpg16x16cropped.jpg";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 879);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 16 ========== */
+ testnum++;
+ testdesc = "test cropping a JPG with an offset";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeCroppedImage(
+ container,
+ "image/jpeg",
+ 16,
+ 16,
+ 16,
+ 16
+ );
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image2jpg16x16cropped2.jpg";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 878);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 17 ========== */
+ testnum++;
+ testdesc = "test cropping a JPG without a given height";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 16, 0);
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image2jpg16x32cropped3.jpg";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 1127);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 18 ========== */
+ testnum++;
+ testdesc = "test cropping a JPG without a given width";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 0, 16);
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image2jpg32x16cropped4.jpg";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 1135);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 19 ========== */
+ testnum++;
+ testdesc = "test cropping a JPG without a given width and height";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 0, 0);
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image2jpg32x32.jpg";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 1634);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 20 ========== */
+ testnum++;
+ testdesc = "test scaling a JPG without a given width";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeScaledImage(container, "image/jpeg", 0, 16);
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image2jpg32x16scaled.jpg";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 1227);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 21 ========== */
+ testnum++;
+ testdesc = "test scaling a JPG without a given height";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeScaledImage(container, "image/jpeg", 16, 0);
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image2jpg16x32scaled.jpg";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 1219);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 22 ========== */
+ testnum++;
+ testdesc = "test scaling a JPG without a given width and height";
+
+ // we'll reuse the container from the previous test
+ istream = imgTools.encodeScaledImage(container, "image/jpeg", 0, 0);
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image2jpg32x32.jpg";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 1634);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 23 ========== */
+ testnum++;
+ testdesc = "test invalid arguments for cropping";
+
+ var numErrors = 0;
+
+ try {
+ // width/height can't be negative
+ imgTools.encodeScaledImage(container, "image/jpeg", -1, -1);
+ } catch (e) {
+ numErrors++;
+ }
+
+ try {
+ // offsets can't be negative
+ imgTools.encodeCroppedImage(container, "image/jpeg", -1, -1, 16, 16);
+ } catch (e) {
+ numErrors++;
+ }
+
+ try {
+ // width/height can't be negative
+ imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, -1, -1);
+ } catch (e) {
+ numErrors++;
+ }
+
+ try {
+ // out of bounds
+ imgTools.encodeCroppedImage(container, "image/jpeg", 17, 17, 16, 16);
+ } catch (e) {
+ numErrors++;
+ }
+
+ try {
+ // out of bounds
+ imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 33, 33);
+ } catch (e) {
+ numErrors++;
+ }
+
+ try {
+ // out of bounds
+ imgTools.encodeCroppedImage(container, "image/jpeg", 1, 1, 0, 0);
+ } catch (e) {
+ numErrors++;
+ }
+
+ Assert.equal(numErrors, 6);
+
+ /* ========== 24 ========== */
+ testnum++;
+ testdesc = "test encoding webp";
+
+ // Load picture that we want to convert
+ imgName = "image1.png";
+ inMimeType = "image/png";
+ imgFile = do_get_file(imgName);
+
+ istream = getFileInputStream(imgFile);
+ Assert.equal(istream.available(), 8415);
+
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ inMimeType
+ );
+
+ // Convert image to webp
+ istream = imgTools.encodeImage(container, "image/webp");
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image1.webp";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 3206);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 25 ========== */
+ testnum++;
+ testdesc = "test encoding webp with quality parameter";
+
+ // Load picture that we want to convert
+ imgName = "image1.png";
+ inMimeType = "image/png";
+ imgFile = do_get_file(imgName);
+
+ istream = getFileInputStream(imgFile);
+ Assert.equal(istream.available(), 8415);
+
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ inMimeType
+ );
+
+ // Convert image to webp
+ istream = imgTools.encodeImage(container, "image/webp", "quality=50");
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image1quality50.webp";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 1944);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== bug 363986 ========== */
+ testnum = 363986;
+ testdesc = "test PNG and JPEG and WEBP encoders' Read/ReadSegments methods";
+
+ var testData = [
+ {
+ preImage: "image3.ico",
+ preImageMimeType: "image/x-icon",
+ refImage: "image3ico16x16.png",
+ refImageMimeType: "image/png",
+ },
+ {
+ preImage: "image1.png",
+ preImageMimeType: "image/png",
+ refImage: "image1png64x64.jpg",
+ refImageMimeType: "image/jpeg",
+ },
+ {
+ preImage: "image1.png",
+ preImageMimeType: "image/png",
+ refImage: "image1.webp",
+ refImageMimeType: "image/webp",
+ },
+ ];
+
+ for (var i = 0; i < testData.length; ++i) {
+ var dict = testData[i];
+
+ imgFile = do_get_file(dict.refImage);
+ istream = getFileInputStream(imgFile);
+ var refBytes = streamToArray(istream);
+
+ imgFile = do_get_file(dict.preImage);
+ istream = getFileInputStream(imgFile);
+
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ dict.preImageMimeType
+ );
+
+ istream = imgTools.encodeImage(container, dict.refImageMimeType);
+
+ var sstream = Cc["@mozilla.org/storagestream;1"].createInstance(
+ Ci.nsIStorageStream
+ );
+ sstream.init(4096, 4294967295, null);
+ var ostream = sstream.getOutputStream(0);
+ var bostream = Cc[
+ "@mozilla.org/network/buffered-output-stream;1"
+ ].createInstance(Ci.nsIBufferedOutputStream);
+
+ // use a tiny buffer to make sure the image data doesn't fully fit in it
+ bostream.init(ostream, 8);
+
+ bostream.writeFrom(istream, istream.available());
+ bostream.flush();
+ bostream.close();
+
+ var encBytes = streamToArray(sstream.newInputStream(0));
+
+ compareArrays(refBytes, encBytes);
+ }
+
+ /* ========== bug 413512 ========== */
+ testnum = 413512;
+ testdesc = "test decoding bad favicon (bug 413512)";
+
+ imgName = "bug413512.ico";
+ inMimeType = "image/x-icon";
+ imgFile = do_get_file(imgName);
+
+ istream = getFileInputStream(imgFile);
+ Assert.equal(istream.available(), 17759);
+ var errsrc = "none";
+
+ try {
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ inMimeType
+ );
+
+ // We expect to hit an error during encoding because the ICO header of the
+ // image is fine, but the actual resources are corrupt. Since
+ // decodeImageFromBuffer() only performs a metadata decode, it doesn't decode
+ // far enough to realize this, but we'll find out when we do a full decode
+ // during encodeImage().
+ try {
+ istream = imgTools.encodeImage(container, "image/png");
+ } catch (e) {
+ err = e;
+ errsrc = "encode";
+ }
+ } catch (e) {
+ err = e;
+ errsrc = "decode";
+ }
+
+ Assert.equal(errsrc, "encode");
+ checkExpectedError(/NS_ERROR_FAILURE/, err);
+
+ /* ========== bug 815359 ========== */
+ testnum = 815359;
+ testdesc = "test correct ico hotspots (bug 815359)";
+
+ imgName = "bug815359.ico";
+ inMimeType = "image/x-icon";
+ imgFile = do_get_file(imgName);
+
+ istream = getFileInputStream(imgFile);
+ Assert.equal(istream.available(), 4286);
+
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ inMimeType
+ );
+
+ Assert.equal(container.hotspotX, 10);
+ Assert.equal(container.hotspotY, 9);
+
+ /* ========== end ========== */
+ } catch (e) {
+ throw new Error(
+ "FAILED in test #" + testnum + " -- " + testdesc + ": " + e
+ );
+ }
+}
diff --git a/image/test/unit/test_moz_icon_uri.js b/image/test/unit/test_moz_icon_uri.js
new file mode 100644
index 0000000000..0111d71d2a
--- /dev/null
+++ b/image/test/unit/test_moz_icon_uri.js
@@ -0,0 +1,157 @@
+/*
+ * Test icon URI functionality
+ *
+ */
+
+// There are 3 types of valid icon URIs:
+// 1. moz-icon:[valid URL]
+// 2. moz-icon://[file name]
+// 3. moz-icon://stock/[icon identifier]
+// Plus we also support moz-icon://[valid URL] for backwards compatibility.
+
+// Main test entry point.
+
+function run_test() {
+ let ioService = Services.io;
+ let currentSpec = ""; // the uri spec that we're currently testing
+ let exception = false; // whether or not an exception was thrown
+ let uri = null; // the current URI
+ let iconURI = null; // the current icon URI
+
+ // Note that if the scheme is not correct the ioservice won't even create an icon URI
+ // so don't bother testing incorrect schemes here.
+
+ // Make sure a valid file name icon URI can be created and that we can obtain
+ // all arguments, the spec, and the file extension.
+ currentSpec = "moz-icon://foo.html?contentType=bar&size=button&state=normal";
+ try {
+ uri = ioService.newURI(currentSpec);
+ } catch (e) {
+ exception = true;
+ }
+ Assert.equal(exception, false);
+ exception = false; // reset exception value
+
+ iconURI = uri.QueryInterface(Ci.nsIMozIconURI);
+ Assert.equal(iconURI.iconSize, "button");
+ Assert.equal(iconURI.iconState, "normal");
+ Assert.equal(iconURI.contentType, "bar");
+ Assert.equal(iconURI.fileExtension, ".html");
+
+ // Make sure a valid file name icon URI can be created with a numeric size,
+ // and make sure the numeric size is handled properly
+ currentSpec = "moz-icon://foo.html?size=3";
+ try {
+ uri = ioService.newURI(currentSpec);
+ } catch (e) {
+ exception = true;
+ }
+ Assert.equal(exception, false);
+ exception = false; // reset exception value
+
+ iconURI = uri.QueryInterface(Ci.nsIMozIconURI);
+ Assert.equal(iconURI.iconSize, "");
+ Assert.equal(iconURI.imageSize, 3);
+
+ // Make sure a valid stock icon URI can be created and that we can obtain
+ // the stock icon's name.
+ currentSpec = "moz-icon://stock/foo";
+ try {
+ uri = ioService.newURI(currentSpec);
+ } catch (e) {
+ exception = true;
+ }
+ Assert.equal(exception, false);
+ exception = false; // reset exception value
+
+ iconURI = uri.QueryInterface(Ci.nsIMozIconURI);
+ Assert.equal(iconURI.stockIcon, "foo");
+
+ // Make sure an invalid stock icon URI, missing icon identifier, throws.
+ currentSpec = "moz-icon://stock/?size=3";
+ try {
+ uri = ioService.newURI(currentSpec);
+ } catch (e) {
+ exception = true;
+ }
+ Assert.ok(exception);
+ exception = false; // reset exception value
+
+ // Make sure a valid file URL icon URI can be created and that we can obtain
+ // the URL and QI it to an nsIFileURL.
+ currentSpec = "moz-icon:file://foo.txt";
+ try {
+ uri = ioService.newURI(currentSpec);
+ } catch (e) {
+ exception = true;
+ }
+ Assert.equal(exception, false);
+ exception = false; // reset exception value
+
+ iconURI = uri.QueryInterface(Ci.nsIMozIconURI);
+ let fileURL = null;
+ try {
+ fileURL = iconURI.iconURL.QueryInterface(Ci.nsIFileURL);
+ } catch (e) {
+ exception = true;
+ }
+ Assert.equal(exception, false);
+ exception = false; // reset exception value
+
+ Assert.notEqual(fileURL, null);
+
+ // Now test a file URI which has been created with an extra //
+ currentSpec = "moz-icon://file://foo.txt";
+ try {
+ uri = ioService.newURI(currentSpec);
+ } catch (e) {
+ exception = true;
+ }
+ Assert.equal(exception, false);
+ exception = false; // reset exception value
+
+ iconURI = uri.QueryInterface(Ci.nsIMozIconURI);
+ fileURL = null;
+ try {
+ fileURL = iconURI.iconURL.QueryInterface(Ci.nsIFileURL);
+ } catch (e) {
+ exception = true;
+ }
+ Assert.equal(exception, false);
+ exception = false; // reset exception value
+
+ Assert.notEqual(fileURL, null);
+
+ // Now test a simple invalid icon URI. This should fail.
+ currentSpec = "moz-icon:foo";
+ try {
+ uri = ioService.newURI(currentSpec);
+ } catch (e) {
+ exception = true;
+ }
+ Assert.equal(exception, true);
+ exception = false; // reset exception value
+
+ // Now test an icon URI that has a URI for a path but that is not a URL. This should fail.
+ // This is png data for a little red dot that I got from wikipedia.
+ currentSpec =
+ "moz-icon:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IAAAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1JREFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jqch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0vr4MkhoXe0rZigAAAABJRU5ErkJggg==";
+ try {
+ uri = ioService.newURI(currentSpec);
+ } catch (e) {
+ exception = true;
+ }
+ Assert.equal(exception, true);
+ exception = false; // reset exception value
+
+ // Now test a URI that should be a file name but is ridiculously long. This should fail.
+ currentSpec =
+ "moz-icon://data:application/vnd.ms-excel;base64,PHhtbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJ1dGYtOCI+PHNzOldvcmtib29rIHhtbG5zOnNzPSJ1cm46c2NoZW1hcy1taWNyb3NvZnQtY29tOm9mZmljZTpzcHJlYWRzaGVldCIgeG1sbnM6eD0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6ZXhjZWwiIHhtbG5zOm89InVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSI+PG86RG9jdW1lbnRQcm9wZXJ0aWVzPjxvOlRpdGxlPkFycmF5IEdyaWQ8L286VGl0bGU+PC9vOkRvY3VtZW50UHJvcGVydGllcz48c3M6RXhjZWxXb3JrYm9vaz48c3M6V2luZG93SGVpZ2h0PjkwMDA8L3NzOldpbmRvd0hlaWdodD48c3M6V2luZG93V2lkdGg+MTc0ODA8L3NzOldpbmRvd1dpZHRoPjxzczpQcm90ZWN0U3RydWN0dXJlPkZhbHNlPC9zczpQcm90ZWN0U3RydWN0dXJlPjxzczpQcm90ZWN0V2luZG93cz5GYWxzZTwvc3M6UHJvdGVjdFdpbmRvd3M+PC9zczpFeGNlbFdvcmtib29rPjxzczpTdHlsZXM+PHNzOlN0eWxlIHNzOklEPSJEZWZhdWx0Ij48c3M6QWxpZ25tZW50IHNzOlZlcnRpY2FsPSJUb3AiIHNzOldyYXBUZXh0PSIxIiAvPjxzczpGb250IHNzOkZvbnROYW1lPSJhcmlhbCIgc3M6U2l6ZT0iMTAiIC8+PHNzOkJvcmRlcnM+PHNzOkJvcmRlciBzczpDb2xvcj0iI2U0ZTRlNCIgc3M6V2VpZ2h0PSIxIiBzczpMaW5lU3R5bGU9IkNvbnRpbnVvdXMiIHNzOlBvc2l0aW9uPSJUb3AiIC8+PHNzOkJvcmRlciBzczpDb2xvcj0iI2U0ZTRlNCIgc3M6V2VpZ2h0PSIxIiBzczpMaW5lU3R5bGU9IkNvbnRpbnVvdXMiIHNzOlBvc2l0aW9uPSJCb3R0b20iIC8+PHNzOkJvcmRlciBzczpDb2xvcj0iI2U0ZTRlNCIgc3M6V2VpZ2h0PSIxIiBzczpMaW5lU3R5bGU9IkNvbnRpbnVvdXMiIHNzOlBvc2l0aW9uPSJMZWZ0IiAvPjxzczpCb3JkZXIgc3M6Q29sb3I9IiNlNGU0ZTQiIHNzOldlaWdodD0iMSIgc3M6TGluZVN0eWxlPSJDb250aW51b3VzIiBzczpQb3NpdGlvbj0iUmlnaHQiIC8+PC9zczpCb3JkZXJzPjxzczpJbnRlcmlvciAvPjxzczpOdW1iZXJGb3JtYXQgLz48c3M6UHJvdGVjdGlvbiAvPjwvc3M6U3R5bGU+PHNzOlN0eWxlIHNzOklEPSJ0aXRsZSI+PHNzOkJvcmRlcnMgLz48c3M6Rm9udCAvPjxzczpBbGlnbm1lbnQgc3M6V3JhcFRleHQ9IjEiIHNzOlZlcnRpY2FsPSJDZW50ZXIiIHNzOkhvcml6b250YWw9IkNlbnRlciIgLz48c3M6TnVtYmVyRm9ybWF0IHNzOkZvcm1hdD0iQCIgLz48L3NzOlN0eWxlPjxzczpTdHlsZSBzczpJRD0iaGVhZGVyY2VsbCI+PHNzOkZvbnQgc3M6Qm9sZD0iMSIgc3M6U2l6ZT0iMTAiIC8+PHNzOkFsaWdubWVudCBzczpXcmFwVGV4dD0iMSIgc3M6SG9yaXpvbnRhbD0iQ2VudGVyIiAvPjxzczpJbnRlcmlvciBzczpQYXR0ZXJuPSJTb2xpZCIgc3M6Q29sb3I9IiNBM0M5RjEiIC8+PC9zczpTdHlsZT48c3M6U3R5bGUgc3M6SUQ9ImV2ZW4iPjxzczpJbnRlcmlvciBzczpQYXR0ZXJuPSJTb2xpZCIgc3M6Q29sb3I9IiNDQ0ZGRkYiIC8+PC9zczpTdHlsZT48c3M6U3R5bGUgc3M6UGFyZW50PSJldmVuIiBzczpJRD0iZXZlbmRhdGUiPjxzczpOdW1iZXJGb3JtYXQgc3M6Rm9ybWF0PSJ5eXl5LW1tLWRkIiAvPjwvc3M6U3R5bGU+PHNzOlN0eWxlIHNzOlBhcmVudD0iZXZlbiIgc3M6SUQ9ImV2ZW5pbnQiPjxzczpOdW1iZXJGb3JtYXQgc3M6Rm9ybWF0PSIwIiAvPjwvc3M6U3R5bGU+PHNzOlN0eWxlIHNzOlBhcmVudD0iZXZlbiIgc3M6SUQ9ImV2ZW5mbG9hdCI+PHNzOk51bWJlckZvcm1hdCBzczpGb3JtYXQ9IjAuMDAwIiAvPjwvc3M6U3R5bGU+PHNzOlN0eWxlIHNzOklEPSJvZGQiPjxzczpJbnRlcmlvciBzczpQYXR0ZXJuPSJTb2xpZCIgc3M6Q29sb3I9IiNDQ0NDRkYiIC8+PC9zczpTdHlsZT48c3M6U3R5bGUgc3M6UGFyZW50PSJvZGQiIHNzOklEPSJvZGRkYXRlIj48c3M6TnVtYmVyRm9ybWF0IHNzOkZvcm1hdD0ieXl5eS1tbS1kZCIgLz48L3NzOlN0eWxlPjxzczpTdHlsZSBzczpQYXJlbnQ9Im9kZCIgc3M6SUQ9Im9kZGludCI+PHNzOk51bWJlckZvcm1hdCBzczpGb3JtYXQ9IjAiIC8+PC9zczpTdHlsZT48c3M6U3R5bGUgc3M6UGFyZW50PSJvZGQiIHNzOklEPSJvZGRmbG9hdCI+PHNzOk51bWJlckZvcm1hdCBzczpGb3JtYXQ9IjAuMDAwIiAvPjwvc3M6U3R5bGU+PC9zczpTdHlsZXM+PHNzOldvcmtzaGVldCBzczpOYW1lPSJBcnJheSBHcmlkIj48c3M6TmFtZXM+PHNzOk5hbWVkUmFuZ2Ugc3M6TmFtZT0iUHJpbnRfVGl0bGVzIiBzczpSZWZlcnNUbz0iPSdBcnJheSBHcmlkJyFSMTpSMiIgLz48L3NzOk5hbWVzPjxzczpUYWJsZSB4OkZ1bGxSb3dzPSIxIiB4OkZ1bGxDb2x1bW5zPSIxIiBzczpFeHBhbmRlZENvbHVtbkNvdW50PSI1IiBzczpFeHBhbmRlZFJvd0NvdW50PSIzMSI+PHNzOkNvbHVtbiBzczpBdXRvRml0V2lkdGg9IjEiIHNzOldpZHRoPSIyNzEiIC8+PHNzOkNvbHVtbiBzczpBdXRvRml0V2lkdGg9IjEiIHNzOldpZHRoPSI3NSIgLz48c3M6Q29sdW1uIHNzOkF1dG9GaXRXaWR0aD0iMSIgc3M6V2lkdGg9Ijc1IiAvPjxzczpDb2x1bW4gc3M6QXV0b0ZpdFdpZHRoPSIxIiBzczpXaWR0aD0iNzUiIC8+PHNzOkNvbHVtbiBzczpBdXRvRml0V2lkdGg9IjEiIHNzOldpZHRoPSI4NSIgLz48c3M6Um93IHNzOkhlaWdodD0iMzgiPjxzczpDZWxsIHNzOlN0eWxlSUQ9InRpdGxlIiBzczpNZXJnZUFjcm9zcz0iNCI+PHNzOkRhdGEgeG1sbnM6aHRtbD0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MCIgc3M6VHlwZT0iU3RyaW5nIj48aHRtbDpCPiAoYykyMDA4IFNFQk4gVUE8L2h0bWw6Qj48L3NzOkRhdGE+PHNzOk5hbWVkQ2VsbCBzczpOYW1lPSJQcmludF9UaXRsZXMiIC8+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3cgc3M6QXV0b0ZpdEhlaWdodD0iMSI+PHNzOkNlbGwgc3M6U3R5bGVJRD0iaGVhZGVyY2VsbCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5Db21wYW55PC9zczpEYXRhPjxzczpOYW1lZENlbGwgc3M6TmFtZT0iUHJpbnRfVGl0bGVzIiAvPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJoZWFkZXJjZWxsIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPlByaWNlPC9zczpEYXRhPjxzczpOYW1lZENlbGwgc3M6TmFtZT0iUHJpbnRfVGl0bGVzIiAvPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJoZWFkZXJjZWxsIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkNoYW5nZTwvc3M6RGF0YT48c3M6TmFtZWRDZWxsIHNzOk5hbWU9IlByaW50X1RpdGxlcyIgLz48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iaGVhZGVyY2VsbCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4lIENoYW5nZTwvc3M6RGF0YT48c3M6TmFtZWRDZWxsIHNzOk5hbWU9IlByaW50X1RpdGxlcyIgLz48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iaGVhZGVyY2VsbCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5MYXN0IFVwZGF0ZWQ8L3NzOkRhdGE+PHNzOk5hbWVkQ2VsbCBzczpOYW1lPSJQcmludF9UaXRsZXMiIC8+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zbSBDbzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj43MS43Mjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjAyPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMDM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5BVCZUIEluYy48L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zMS42MTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPi0wLjQ4PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+LTEuNTQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5BbGNvYSBJbmM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MjkuMDE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC40Mjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xLjQ3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+QWx0cmlhIEdyb3VwIEluYzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjgzLjgxPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4yODwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMzQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5BbWVyaWNhbiBFeHByZXNzIENvbXBhbnk8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NTIuNTU8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wMTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjAyPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+QW1lcmljYW4gSW50ZXJuYXRpb25hbCBHcm91cCwgSW5jLjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjY0LjEzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4zMTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuNDk8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5Cb2VpbmcgQ28uPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjc1LjQzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuNTM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC43MTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkNhdGVycGlsbGFyIEluYy48L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj42Ny4yNzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuOTI8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xLjM5PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+Q2l0aWdyb3VwLCBJbmMuPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjQ5LjM3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMDI8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wNDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkUuSS4gZHUgUG9udCBkZSBOZW1vdXJzIGFuZCBDb21wYW55PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NDAuNDg8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjUxPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MS4yODwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkV4eG9uIE1vYmlsIENvcnA8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NjguMTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4tMC40Mzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4tMC42NDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkdlbmVyYWwgRWxlY3RyaWMgQ29tcGFueTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjM0LjE0PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+LTAuMDg8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4tMC4yMzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkdlbmVyYWwgTW90b3JzIENvcnBvcmF0aW9uPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjMwLjI3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjEuMDk8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+My43NDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkhld2xldHQtUGFja2FyZCBDby48L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zNi41Mzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPi0wLjAzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+LTAuMDg8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5Ib25leXdlbGwgSW50bCBJbmM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MzguNzc8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wNTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjEzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+SW50ZWwgQ29ycG9yYXRpb248L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xOS44ODwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMzE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xLjU4PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+SW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lczwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj44MS40MTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjQ0PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuNTQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5KUCBNb3JnYW4gJiBDaGFzZSAmIENvPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NDUuNzM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjA3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4xNTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkpvaG5zb24gJiBKb2huc29uPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjY0LjcyPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMDY8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wOTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPk1jRG9uYWxkJ3MgQ29ycG9yYXRpb248L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zNi43Njwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuODY8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4yLjQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5NZXJjayAmIENvLiwgSW5jLjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj40MC45Njwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjQxPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjEuMDE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5NaWNyb3NvZnQgQ29ycG9yYXRpb248L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4yNS44NDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMTQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjU0PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+UGZpemVyIEluYzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4yNy45Njwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MS40NTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPlRoZSBDb2NhLUNvbGEgQ29tcGFueTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjQ1LjA3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4yNjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuNTg8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5UaGUgSG9tZSBEZXBvdCwgSW5jLjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zNC42NDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjM1PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjEuMDI8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5UaGUgUHJvY3RlciAmIEdhbWJsZSBDb21wYW55PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NjEuOTE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjAxPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wMjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPlVuaXRlZCBUZWNobm9sb2dpZXMgQ29ycG9yYXRpb248L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NjMuMjY8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC41NTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjg4PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+VmVyaXpvbiBDb21tdW5pY2F0aW9uczwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjM1LjU3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4zOTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjEuMTE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XYWwtTWFydCBTdG9yZXMsIEluYy48L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NDUuNDU8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC43Mzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xLjYzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PC9zczpUYWJsZT48eDpXb3Jrc2hlZXRPcHRpb25zPjx4OlBhZ2VTZXR1cD48eDpMYXlvdXQgeDpDZW50ZXJIb3Jpem9udGFsPSIxIiB4Ok9yaWVudGF0aW9uPSJMYW5kc2NhcGUiIC8+PHg6Rm9vdGVyIHg6RGF0YT0iUGFnZSAmYW1wO1Agb2YgJmFtcDtOIiB4Ok1hcmdpbj0iMC41IiAvPjx4OlBhZ2VNYXJnaW5zIHg6VG9wPSIwLjUiIHg6UmlnaHQ9IjAuNSIgeDpMZWZ0PSIwLjUiIHg6Qm90dG9tPSIwLjgiIC8+PC94OlBhZ2VTZXR1cD48eDpGaXRUb1BhZ2UgLz48eDpQcmludD48eDpQcmludEVycm9ycz5CbGFuazwveDpQcmludEVycm9ycz48eDpGaXRXaWR0aD4xPC94OkZpdFdpZHRoPjx4OkZpdEhlaWdodD4zMjc2NzwveDpGaXRIZWlnaHQ+PHg6VmFsaWRQcmludGVySW5mbyAvPjx4OlZlcnRpY2FsUmVzb2x1dGlvbj42MDA8L3g6VmVydGljYWxSZXNvbHV0aW9uPjwveDpQcmludD48eDpTZWxlY3RlZCAvPjx4OkRvTm90RGlzcGxheUdyaWRsaW5lcyAvPjx4OlByb3RlY3RPYmplY3RzPkZhbHNlPC94OlByb3RlY3RPYmplY3RzPjx4OlByb3RlY3RTY2VuYXJpb3M+RmFsc2U8L3g6UHJvdGVjdFNjZW5hcmlvcz48L3g6V29ya3NoZWV0T3B0aW9ucz48L3NzOldvcmtzaGVldD48L3NzOldvcmtib29rPg==";
+ try {
+ uri = ioService.newURI(currentSpec);
+ } catch (e) {
+ exception = true;
+ }
+ Assert.equal(exception, true);
+ exception = false; // reset exception value
+}
diff --git a/image/test/unit/test_private_channel.js b/image/test/unit/test_private_channel.js
new file mode 100644
index 0000000000..008f6aad92
--- /dev/null
+++ b/image/test/unit/test_private_channel.js
@@ -0,0 +1,166 @@
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
+
+const ReferrerInfo = Components.Constructor(
+ "@mozilla.org/referrer-info;1",
+ "nsIReferrerInfo",
+ "init"
+);
+
+var server = new HttpServer();
+server.registerPathHandler("/image.png", imageHandler);
+server.start(-1);
+
+/* import-globals-from image_load_helpers.js */
+load("image_load_helpers.js");
+
+var gHits = 0;
+
+var gIoService = Services.io;
+var gPublicLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
+ Ci.imgILoader
+);
+var gPrivateLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
+ Ci.imgILoader
+);
+gPrivateLoader.QueryInterface(Ci.imgICache).respectPrivacyNotifications();
+
+var nonPrivateLoadContext = Cu.createLoadContext();
+var privateLoadContext = Cu.createPrivateLoadContext();
+
+function imageHandler(metadata, response) {
+ gHits++;
+ response.setHeader("Cache-Control", "max-age=10000", false);
+ response.setStatusLine(metadata.httpVersion, 200, "OK");
+ response.setHeader("Content-Type", "image/png", false);
+ var body = atob(
+ "iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII="
+ );
+ response.bodyOutputStream.write(body, body.length);
+}
+
+var requests = [];
+var listeners = [];
+
+var gImgPath = "http://localhost:" + server.identity.primaryPort + "/image.png";
+
+function setup_chan(path, isPrivate, callback) {
+ var uri = NetUtil.newURI(gImgPath);
+ var securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL;
+ var principal = Services.scriptSecurityManager.createContentPrincipal(uri, {
+ privateBrowsingId: isPrivate ? 1 : 0,
+ });
+ var chan = NetUtil.newChannel({
+ uri,
+ loadingPrincipal: principal,
+ securityFlags,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_IMAGE,
+ });
+ chan.notificationCallbacks = isPrivate
+ ? privateLoadContext
+ : nonPrivateLoadContext;
+ var channelListener = new ChannelListener();
+ chan.asyncOpen(channelListener);
+
+ var listener = new ImageListener(null, callback);
+ var outlistener = {};
+ var loader = isPrivate ? gPrivateLoader : gPublicLoader;
+ var outer = Cc["@mozilla.org/image/tools;1"]
+ .getService(Ci.imgITools)
+ .createScriptedObserver(listener);
+ listeners.push(outer);
+ requests.push(
+ loader.loadImageWithChannelXPCOM(chan, outer, null, outlistener)
+ );
+ channelListener.outputListener = outlistener.value;
+ listener.synchronous = false;
+}
+
+function loadImage(isPrivate, callback) {
+ var listener = new ImageListener(null, callback);
+ var outer = Cc["@mozilla.org/image/tools;1"]
+ .getService(Ci.imgITools)
+ .createScriptedObserver(listener);
+ var uri = gIoService.newURI(gImgPath);
+ var loadGroup = Cc["@mozilla.org/network/load-group;1"].createInstance(
+ Ci.nsILoadGroup
+ );
+ loadGroup.notificationCallbacks = isPrivate
+ ? privateLoadContext
+ : nonPrivateLoadContext;
+ var loader = isPrivate ? gPrivateLoader : gPublicLoader;
+ var referrerInfo = new ReferrerInfo(
+ Ci.nsIReferrerInfo.NO_REFERRER_WHEN_DOWNGRADE,
+ true,
+ null
+ );
+ requests.push(
+ loader.loadImageXPCOM(
+ uri,
+ null,
+ referrerInfo,
+ null,
+ loadGroup,
+ outer,
+ null,
+ 0,
+ null
+ )
+ );
+ listener.synchronous = false;
+}
+
+function run_loadImage_tests() {
+ function observer() {
+ Services.obs.removeObserver(observer, "cacheservice:empty-cache");
+ gHits = 0;
+ loadImage(false, function () {
+ loadImage(false, function () {
+ loadImage(true, function () {
+ loadImage(true, function () {
+ Assert.equal(gHits, 2);
+ server.stop(do_test_finished);
+ });
+ });
+ });
+ });
+ }
+
+ for (let loader of [gPublicLoader, gPrivateLoader]) {
+ loader.QueryInterface(Ci.imgICache).clearCache(true);
+ loader.QueryInterface(Ci.imgICache).clearCache(false);
+ }
+ Services.obs.addObserver(observer, "cacheservice:empty-cache");
+ let cs = Services.cache2;
+ cs.clear();
+}
+
+function cleanup() {
+ for (var i = 0; i < requests.length; ++i) {
+ requests[i].cancelAndForgetObserver(0);
+ }
+}
+
+function run_test() {
+ registerCleanupFunction(cleanup);
+
+ do_test_pending();
+
+ Services.prefs.setBoolPref("network.http.rcwn.enabled", false);
+
+ // We create a public channel that loads an image, then an identical
+ // one that should cause a cache read. We then create a private channel
+ // and load the same image, and do that a second time to ensure a cache
+ // read. In total, we should cause two separate http responses to occur,
+ // since the private channels shouldn't be able to use the public cache.
+ setup_chan("/image.png", false, function () {
+ setup_chan("/image.png", false, function () {
+ setup_chan("/image.png", true, function () {
+ setup_chan("/image.png", true, function () {
+ Assert.equal(gHits, 2);
+ run_loadImage_tests();
+ });
+ });
+ });
+ });
+}
diff --git a/image/test/unit/xpcshell.ini b/image/test/unit/xpcshell.ini
new file mode 100644
index 0000000000..7ce8a02e1e
--- /dev/null
+++ b/image/test/unit/xpcshell.ini
@@ -0,0 +1,42 @@
+[DEFAULT]
+head =
+support-files =
+ async_load_tests.js
+ bug413512.ico
+ bug815359.ico
+ image1.png
+ image1.webp
+ image1quality50.webp
+ image1png16x16.jpg
+ image1png64x64.jpg
+ image2.jpg
+ image2jpg16x16-win.png
+ image2jpg16x16.png
+ image2jpg16x16cropped.jpg
+ image2jpg16x16cropped2.jpg
+ image2jpg16x32cropped3.jpg
+ image2jpg16x32scaled.jpg
+ image2jpg32x16cropped4.jpg
+ image2jpg32x16scaled.jpg
+ image2jpg32x32-win.png
+ image2jpg32x32.jpg
+ image2jpg32x32.png
+ image3.ico
+ image3ico16x16.png
+ image3ico32x32.png
+ image4.gif
+ image4gif16x16bmp24bpp.ico
+ image4gif16x16bmp32bpp.ico
+ image4gif32x32bmp24bpp.ico
+ image4gif32x32bmp32bpp.ico
+ image_load_helpers.js
+
+
+[test_async_notification.js]
+[test_async_notification_404.js]
+[test_async_notification_animated.js]
+[test_encoder_apng.js]
+[test_encoder_png.js]
+[test_imgtools.js]
+[test_moz_icon_uri.js]
+[test_private_channel.js]